Set-up

rm(list = ls())
library(dplyr)
library(wesanderson)
library(GillespieSSA)
library(tidyverse)

Background

The traditionally held belief that most modern infectious diseases emerged when humans began living in larger agricultural settlements has been challenged by studies of modern hunter-gatherers. This study will investigate which emerging pathogens may persist in hunter-gatherer groups by constructing a compartment model of infectious disease transmission that accounts for demography and multi-band structure. This study will look to understand how the critical community size required to sustain an outbreak is affected by host population dynamics. We show that metapopulation structure increases the probability of a respiratory pathogen with waning immunity persisting after 3 years. The probability of persistence increases with the number of sub-populations but is largely determined by the duration of immunity. Understanding the origins of infectious diseases is an important area of research that will lead to improved strategies for reducing their global burden.

This report will cover the full analysis undertaken to generate the results used in my MSc project. A full description of the research project aims and methods can be found in the final paper in the Hunter_Gatherer_models GitHub repository. Some code used in this project was adapted from the tutorials attached to the GillespieSSA package.

Model Parameter estimation

Agta Hunter-Gatherer Demography

Modern-day hunter-gatherers are often used to make inferences about pre-agricultural human populations. This study modeled the host population on a group of indigenous hunter-gatherers from the Northern Phillipines known as the Agta. Information regarding births, deaths and population size were obtain from a study conducted by Headland et al., (2011). Authors conducted a census-like survey of the Agta that followed $$4,300 individuals over the period of 1950-2010. This date was first explored to understand Agta demography.

agta_demo <- read.csv("Agta_Data/AgtaPopDynamics_Headland2007.csv")

ggplot(agta_demo, aes(x=Year)) +
  geom_line(aes(y=PopSize), colour = wes_palettes$Darjeeling1[1]) +
  geom_line(aes(y=Births), colour = wes_palettes$Darjeeling1[2]) +
  geom_line(aes(y=Deaths), colour = wes_palettes$Darjeeling1[3]) +
  theme_bw()

Population Size

hist(agta_demo$PopSize)

summary(agta_demo$PopSize)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  133.0   177.0   213.0   211.4   228.0   295.0 

Births

hist(agta_demo$Births)

summary(agta_demo$Births)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
   4.00    8.00   10.00   10.33   12.25   15.00       1 

Deaths

hist(agta_demo$Deaths)

summary(agta_demo$Deaths)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
  2.000   5.000   7.000   7.683  10.000  23.000       1 

Birth/Death rate per person per day

Birth rate was estimated from this data by taking the mean of the annual number of births divided by two times the annual number of females. This was then scaled appropriately to obtain the daily mean birth rate per person.

agta_demo <- agta_demo %>%
  mutate(Birth_rate = Births/(Female*2),
         Birth_rate_daily = (1 + Birth_rate) ^ (1/365) - 1,
         Death_rate = (Deaths/PopSize),
         Death_rate_daily = (1 + Death_rate) ^ (1/365) - 1,
         PopChange = (diff = PopSize - lag(PopSize, default = first(PopSize))),
         PopChange_rate = abs(PopChange)/PopSize,
         PopChange_rate_daily = (1 + PopChange_rate) ^ (1/365) - 1)
head(agta_demo)


hist(agta_demo$Birth_rate)

hist(agta_demo$Death_rate)


ggplot(agta_demo, aes(x=Year)) +
  geom_line(aes(y=Birth_rate), colour = wes_palettes$Darjeeling1[2]) +
  geom_line(aes(y=Death_rate), colour = wes_palettes$Darjeeling1[3]) +
  theme_bw()


demo_sum <- agta_demo %>%
  select(PopSize, Birth_rate, Birth_rate_daily, Death_rate, Death_rate_daily, PopChange_rate, PopChange_rate_daily) %>%
    summarise(across(
    .cols = is.numeric, 
    .fns = list(Mean = mean, SD = sd), na.rm = TRUE, 
    .names = "{col}_{fn}"
    ))
demo_sum 

demo_sum <- as.list(demo_sum)

Agta Band Size

Data regarding camp size of Agta hunter-gatherers was obtained from a study of 615 individuals from 15 camps in in the municipality of Palanan, the Northern Philippines published by Dyble et al. (2021).

# Import Camp data from Mark Dyble
camps.data <- read_csv("Agta_Data/camps.csv")
New names:Rows: 15 Columns: 9── Column specification ──────────────────────────────────────────────────────
Delimiter: ","
chr (1): camp_name
dbl (8): ...1, camp_total, camp_adult_men, camp_adult_women, camp_all_r, c...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(camps.data)
# Explore camp size
hist(camps.data$camp_total)


camp.size <- camps.data %>%
  summarise(mean = mean(camp_total),
            sd = sd(camp_total),
            min = min(camp_total),
            max = max(camp_total),
            var = var(camp_total))
camp.size

Pathogen X

For the purpose of this investigation we formulated a hypothetical respiratory pathogen, referred to as pathogen X. Taking into account the biological trade-offs between high transmissibility and high pathogenicity, pathogen X was decided to be highly infectious with a relatively low case fatality rate of 0.005. Transmission occurred via close contact with an infected individual. Infection was characterised by a latent period of 5.7 days followed by an infectious period of 5 days. Individuals who recovered from infection were immune for 100 days, after which immunity waned and individuals became susceptible to re-infection. Based on these characteristics, the parameters in table 1 were assumed and input into the final models.

Parameter Rate Value
\(\beta\) Transmission 0.6
\(\sigma\) Infectious 0.175
\(\gamma\) Recovery 0.2
\(\alpha\) Death from Infection 0.001
\(\omega\) Waning Immunity 0.01

Single Population Model

To investigate the persistence of a hypothetical respiratory pathogen in hunter-gatherers, this study chose to simulate disease transmission using a compartment model approach as outlined in the introduction. Two models were constructed to investigate compare the effect of metapopulation structure on disease persistence. This first describes the transmission of a pathogen within a single population with demography and waning immunity to re-infection over time.


Figure 1 - Flow diagram of SEIRS model of transmission
Figure 1 - Flow diagram of SEIRS model of transmission




\[\begin{align*} \frac{{{\mathrm{d}}S}}{{{\mathrm{d}}t}} & = \underbrace {\mu N}_{{\mathrm{birth}}}~ - ~\underbrace {\frac{\beta SI}{N}}_{{\mathrm{infection}}}~~ + \underbrace {\omega R}_{{\mathrm{lost}}\,{\mathrm{immunity}}} - \underbrace {\mu S}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}E}}{{{\mathrm{d}}t}} & = \underbrace {\frac{\beta SI}{N}}_{{\mathrm{infection}}}~ - ~\underbrace {\sigma E}_{{\mathrm{latency}}} - \underbrace {\mu E}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}I}}{{{\mathrm{d}}t}} & = \underbrace {\sigma E}_{{\mathrm{latency}}} - \underbrace {\gamma I}_{{\mathrm{recovery}}} - ~\underbrace {\left( {\mu + \alpha } \right)I}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}R}}{{{\mathrm{d}}t}} & = \underbrace {\gamma I}_{{\mathrm{recovery}}} - \underbrace {\omega R}_{{\mathrm{lost}}\ {\mathrm{immunity}}} - \underbrace {\mu R}_{{\mathrm{death}}} \end{align*}\]



Where transmission is frequency dependent, \({\frac{\beta SI}{N}}\), \(\frac{1}{\sigma}\) is the duration of the latent phase, \(\frac{1}{\gamma}\) is the duration of infection, \(\frac{1}{\omega}\) is the duration of immunity and death from infection occurs at the rate \(\alpha\). Individuals can be born into S and die naturally from any compartment at a rate of \(\mu\).

Model Set-up

Model was set up with a single randomly selected camp size with a single infected individual and parameters for pathogen X.

# Define Paramenters
N <-    sample(camps.data$camp_total, 1)    # Population size
initial_infected <-  1    # Initial infected
simName <- "SEIRS model"       # Simulation name
tf <- 365*3

#Collect parameters
parms <- list(
  beta = 0.6,
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

#Create the named initial state vector for the U-patch system.

x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

names(x0) <- c("S","E","I", "R", "N")


# Define the state change matrix for a single patch
nu <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
a <-c(
        paste0("(beta*I/N)*S"), # Infection
        paste0("sigma*E"),                                       # Becomes infecious
        paste0("gamma*I"),                                       # Recovery from infection
        paste0("omega*R"),       # Loss of immunity
        paste0("mu*N"),                             # Births
        paste0("mu*S"),                                             # Deaths (S)
        paste0("mu*E"),                                             # Deaths (E)
        paste0("mu*I"),                                             # Deaths (I)
        paste0("mu*R"),                                             # Deaths (R)
        paste0("alpha*I")                                           # Deaths from infection
        
      )

Define functions to calculate R0 and expected number of susceptibles at equilibrium, and critical community size (Diekmann et al., 2012).

infectious_period
Error: object 'infectious_period' not found

Calculate Epidemic Statistics

<<<<<<< HEAD The expected number of secondary cases from a single infected individual in an entirely susceptible population, also known as the basic reproduction number (\(R_0\)), was calculated for pathogen X in both the single and meta population model. In the single population SEIRS model, \(R_0\) may be estimated~(Bjørnstad, 2023):

\[\begin{equation} R_0 = \frac{\sigma}{\sigma + \mu}*\frac{\beta}{\gamma + \mu + \alpha} \end{equation}\]

In the metapopulation model, the same equation was applied across the next-generation matrix and the eigenvalue calculated to infer \(R_0\) across all patches. To provide an estimate for the number of individuals required to sustain endemic spread of pathogen X in a single population, I calculated the critical community size (CCS) (Diekmann, Heesterbeek, and Britton, 2012):

\[\begin{equation} N_c = \frac{1}{\epsilon^2(1-\frac{1}{R_0})^2} \end{equation}\]

Where \(N_c\) is the CCS above which endemic spread may be sustained and \(\epsilon\) is the ratio of the average length of the infectious period to the life expectancy of the host. The CCS represents the minimum population size required to prevent disease extinction. A crude average life expectancy of 23 years was used to describe Agta hunter-gatherers as published by~ Gurven and Kaplan (2007).

The expected proportion of infected individuals at endemic equilibrium, \(I^*\), was also calculated in the single population model~(Keeling and Rohani, 2008):

\[\begin{equation} I^* = \frac{(R_0 - 1)\omega}{\gamma R_0} \end{equation}\]

======= >>>>>>> 672728028f18b2fc224322993d245c9a6ee71bf1


# Calculate R0, expected number of infecteds at equilibrium, magnitude of oscillation and CCS
R0_single <- R0(parms)
R0_single

EIE_single <- EIE(R0_single, parms) # proportion of expected infecteds at equilibrium
EIE_single

expexted_infecteds <- EIE_single*N # number of expected infecteds at equilibrium
expexted_infecteds

sqrt(N) # magnitude of oscillations 

CCS_single <- CCS(infectious_period = 5, R0 = R0_single) # Average life expectancy as per Kaplan (crude)
CCS_single

Plot CCS by infectious period and R0

<<<<<<< HEAD

Parameter space of CCS equation was explored with infectious period ranging from 5 to 365 days and \(R_0\) ranging from 1.1 to 5.

infectious_periods <- seq(5, 365, 10)

=======
infectious_periods <- seq(5, 365, 10)

>>>>>>> 672728028f18b2fc224322993d245c9a6ee71bf1
R0_seq <- seq(1.1,5,0.2)

x = infectious_periods

y = R0_seq

z = log10(outer(x, y, CCS))

persp3D(x, y, z,
        zlim = c(0,10),
        xlim = c(5, 365),
        ylim = c(1, 5),
        xlab = "Infectious Period (days)",
        ylab = "Basic Reproductive number (R0)",
        zlab = "log10(Critcal Community Size)",
        shade =  0.15, theta = 140, phi = 30, expand = 0.6,
        ticktype = "detailed")

Run Single Population Model

# Run simulations with the Direct method
set.seed(21)
out <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
) 



## Extra Plots
plot_data <- out$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

single_plot <- ggplot(data = plot_data, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  labs(x="Time (Days)",
       y="Number of Individuals", 
       colour="State")+
  geom_hline(yintercept = expexted_infecteds, linetype = 'dashed') +
  theme_bw()

single_plot

#ggsave(filename = "single_plot.pdf", 
       #plot = single_plot,
       #device = "pdf",
       #width = 7, 
       #height = 3,
       #path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
plot_data %>%
  filter(state == "I") %>%
  slice_max(count)

Outbreak peaked at day 25 with 14 infected individuals.

## Run multiple simulations and saving output
num_sims <- 1000
sim_list <- list()
sim_list <- vector("list", length = num_sims)

for (i in 1:num_sims){
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  set.seed(i)
  out_100 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data <- out_100$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list[[i]] <- sim_data
}

sim_output <- bind_rows(sim_list)
# Summary table of endpoint data
sim_output <- sim_output %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
head(sim_output)

# Make Summary Table of output
sim_summary <- sim_output %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100, 
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary

Varying waining immunity

Waning immunity was thought to play an important role in the persistence of pathogen X so we incrementally increased the duration of immunity (by decreasing \(\omega\)) and calculated the probability of persistence after 3 years in 1000 stochastic simulations. Duration of immunity was increased from 1 day to a year.

0 Days

#Collect parameters
parms_0 <- parms
parms_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_0 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_0 <- out_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_0 <- ggplot(data = plot_data_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_0 <- list()
sim_list_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_0 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_0 <- out_100_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_0[[i]] <- sim_data_0
}

sim_output_0 <- bind_rows(sim_list_0)
# Summary table of endpoint data
sim_output_0 <- sim_output_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_0

# Make Summary Table of output
sim_summary_0 <- sim_output_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_0

1 Days

#Collect parameters
parms_1 <- parms
parms_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_1 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_1 <- out_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_1 <- ggplot(data = plot_data_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_1
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_1 <- list()
sim_list_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_1 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_1 <- out_100_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_1[[i]] <- sim_data_1
}

sim_output_1 <- bind_rows(sim_list_1)
# Summary table of endpoint data
sim_output_1 <- sim_output_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_1

# Make Summary Table of output
sim_summary_1 <- sim_output_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_1

3 Days

#Collect parameters
parms_3 <- parms
parms_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_3 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3 <- out_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3 <- ggplot(data = plot_data_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3 <- list()
sim_list_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_3 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3 <- out_100_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_3[[i]] <- sim_data_3
}

sim_output_3 <- bind_rows(sim_list_3)
# Summary table of endpoint data
sim_output_3 <- sim_output_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3

# Make Summary Table of output
sim_summary_3 <- sim_output_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3

7 Days

#Collect parameters
parms_7 <- parms
parms_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_7 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_7 <- out_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_7 <- ggplot(data = plot_data_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_7
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_7 <- list()
sim_list_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_7 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_7 <- out_100_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_7[[i]] <- sim_data_7
}

sim_output_7 <- bind_rows(sim_list_7)
# Summary table of endpoint data
sim_output_7 <- sim_output_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_7

# Make Summary Table of output
sim_summary_7 <- sim_output_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_7

10 Days

#Collect parameters
parms_10 <- parms
parms_10$omega <- 1/10


# Run simulations with the Direct method
set.seed(4)
out_10 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_10 <- out_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_10 <- ggplot(data = plot_data_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_10 <- list()
sim_list_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_10 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_10 <- out_100_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_10[[i]] <- sim_data_10
}

sim_output_10 <- bind_rows(sim_list_10)
# Summary table of endpoint data
sim_output_10 <- sim_output_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_10

# Make Summary Table of output
sim_summary_10 <- sim_output_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_10

20 Days

#Collect parameters
parms_20 <- parms
parms_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_20 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_20 <- out_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_20 <- ggplot(data = plot_data_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_20 <- list()
sim_list_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_20 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_20 <- out_100_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_20[[i]] <- sim_data_20
}

sim_output_20 <- bind_rows(sim_list_20)
# Summary table of endpoint data
sim_output_20 <- sim_output_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_20

# Make Summary Table of output
sim_summary_20 <- sim_output_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_20

30 Days

#Collect parameters
parms_30 <- parms
parms_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_30 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_30 <- out_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_30 <- ggplot(data = plot_data_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_30 <- list()
sim_list_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_30 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_30 <- out_100_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_30[[i]] <- sim_data_30
}

sim_output_30 <- bind_rows(sim_list_30)
# Summary table of endpoint data
sim_output_30 <- sim_output_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_30

# Make Summary Table of output
sim_summary_30 <- sim_output_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_30

40 Days

#Collect parameters
parms_40 <- parms
parms_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_40 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_40 <- out_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_40 <- ggplot(data = plot_data_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_40 <- list()
sim_list_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_40 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_40 <- out_100_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_40[[i]] <- sim_data_40
}

sim_output_40 <- bind_rows(sim_list_40)
# Summary table of endpoint data
sim_output_40 <- sim_output_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_40

# Make Summary Table of output
sim_summary_40 <- sim_output_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_40

50 Days

#Collect parameters
parms_50 <- parms
parms_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_50 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_50 <- out_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_50 <- ggplot(data = plot_data_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_50 <- list()
sim_list_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_50 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_50 <- out_100_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_50[[i]] <- sim_data_50
}

sim_output_50 <- bind_rows(sim_list_50)
# Summary table of endpoint data
sim_output_50 <- sim_output_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_50

# Make Summary Table of output
sim_summary_50 <- sim_output_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_50

60 Days

#Collect parameters
parms_60 <- parms
parms_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_60 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_60 <- out_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_60 <- ggplot(data = plot_data_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_60 <- list()
sim_list_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_60 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_60 <- out_100_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_60[[i]] <- sim_data_60
}

sim_output_60 <- bind_rows(sim_list_60)
# Summary table of endpoint data
sim_output_60 <- sim_output_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_60

# Make Summary Table of output
sim_summary_60 <- sim_output_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_60

70 Days

#Collect parameters
parms_70 <- parms
parms_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_70 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_70 <- out_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_70 <- ggplot(data = plot_data_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_70 <- list()
sim_list_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_70 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_70 <- out_100_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_70[[i]] <- sim_data_70
}

sim_output_70 <- bind_rows(sim_list_70)
# Summary table of endpoint data
sim_output_70 <- sim_output_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_70

# Make Summary Table of output
sim_summary_70 <- sim_output_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_70

80 Days

#Collect parameters
parms_80 <- parms
parms_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_80 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_80 <- out_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_80 <- ggplot(data = plot_data_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_80 <- list()
sim_list_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_80 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_80 <- out_100_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_80[[i]] <- sim_data_80
}

sim_output_80 <- bind_rows(sim_list_80)
# Summary table of endpoint data
sim_output_80 <- sim_output_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_80

# Make Summary Table of output
sim_summary_80 <- sim_output_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_80

150 Days

#Collect parameters
parms_150 <- parms
parms_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_150 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_150 <- out_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_150 <- ggplot(data = plot_data_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_150 <- list()
sim_list_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_150 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_150 <- out_100_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_150[[i]] <- sim_data_150
}

sim_output_150 <- bind_rows(sim_list_150)
# Summary table of endpoint data
sim_output_150 <- sim_output_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_150

# Make Summary Table of output
sim_summary_150 <- sim_output_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_150

180 Days

#Collect parameters
parms_180 <- parms
parms_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(4)
out_100 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_180 <- out_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_180 <- ggplot(data = plot_data_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_180 <- list()
sim_list_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_180 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_180 <- out_100_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_180[[i]] <- sim_data_180
}

sim_output_180 <- bind_rows(sim_list_180)
# Summary table of endpoint data
sim_output_180 <- sim_output_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_180

# Make Summary Table of output
sim_summary_180 <- sim_output_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_180

365 Days

#Collect parameters
parms_365 <- parms
parms_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_365 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_365 <- out_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_365 <- ggplot(data = plot_data_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_365 <- list()
sim_list_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
 N_a <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N_a - initial_infected, initial_infected, 0, 0,N_a)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_365 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_365 <- out_100_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_365[[i]] <- sim_data_365
}

sim_output_365 <- bind_rows(sim_list_365)
# Summary table of endpoint data
sim_output_365 <- sim_output_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_365

# Make Summary Table of output
sim_summary_365 <- sim_output_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_365

Results

waning_results_single <- sim_summary %>%
  bind_rows(sim_summary_1) %>%
  bind_rows(sim_summary_3) %>%
  bind_rows(sim_summary_7) %>%
  bind_rows(sim_summary_10) %>%
  bind_rows(sim_summary_20) %>%
  bind_rows(sim_summary_30) %>%
  bind_rows(sim_summary_40) %>%
  bind_rows(sim_summary_50) %>%
  bind_rows(sim_summary_60) %>%
  bind_rows(sim_summary_70) %>%
  bind_rows(sim_summary_80) %>%
  bind_rows(sim_summary_100) %>%
  bind_rows(sim_summary_150) %>%
  bind_rows(sim_summary_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model="single",
         patches = 1)

write_csv(waning_results_single, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_single.csv")

waning_results_single
ggplot(waning_results_single, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

7-Patch Metapopulation Model

Recent studies have suggested that pre-agricultural hunter-gatherers did not live in small isolated groups but fromed interconnected multi-camp networks. To investigate this we built a second population that accounts for metapopulation structure of hunter-gatherers. The second model follows an almost identical format as the single population model, but instead has been expanded to accommodate the metapopulation structure of multi-band hunter-gatherer groups:

\[\begin{align*} \frac{{{\mathrm{d}}S}}{{{\mathrm{d}}t}} & = \underbrace {\mu_i N_i}_{{\mathrm{birth}}}~ - ~\underbrace {\biggl(\frac{\beta_{ii} I_i}{N_i} + \frac{\beta_{ji} I_j} {N_j} + ... \biggr)S_i}_{{\mathrm{infection}}}~~ + \underbrace {\omega_i R_i}_{{\mathrm{lost}}\,{\mathrm{immunity}}} - \underbrace {\mu_i S_i}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}E}}{{{\mathrm{d}}t}} & = \underbrace {\biggl(\frac{\beta_{ii} I_i}{N_i} + \frac{\beta_{ji} I_j} {N_j} + ... \biggr)S_i}_{{\mathrm{infection}}}~ - ~\underbrace {\sigma_i E_i}_{{\mathrm{latency}}} - \underbrace {\mu_i E_i}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}I}}{{{\mathrm{d}}t}} & = \underbrace {\sigma_i E_i}_{{\mathrm{latency}}} - \underbrace {\gamma_i I_i}_{{\mathrm{recovery}}} - ~\underbrace {\left( {\mu_i + \alpha_i } \right)I_i}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}R}}{{{\mathrm{d}}t}} & = \underbrace {\gamma_i I_i}_{{\mathrm{recovery}}} - \underbrace {\omega_i R_i}_{{\mathrm{lost}}\ {\mathrm{immunity}}} - \underbrace {\mu_i R_i}_{{\mathrm{death}}} \end{align*}\]

These coupled differential equations describe the within-patch SEIRS-type dynamics of the \(i\)th patch where the force of infection is driven by contact of susceptibles with infecteds within the \(i\)th patch and in the \(j\)th other patches. Both models assume that compartments are well-mixed and that the waiting times between compartments are exponentially distributed.

Model Set-up

We first modeled transmission in a metapopulation of 7 camps, as observed by Migliano et al. (2023), with one initially infected individual from a randomly selected patch.

# Define Paramenters
patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Patch size
U <- length(patchPopSize)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize[i])
  }
))

names(x0_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Define functions for calculating R0 from next-generation matrix

# Calculate R0 from NGM

R0ngm <- function(nextgen_matrix) {
  eigenvalues = eigen(nextgen_matrix, only.values = T)
  R0 = max(abs(eigenvalues$values))
  return(R0)
}

beta.ngm <- function(beta_matrix) {
  eigenvalues = eigen(beta_matrix, only.values = T)
  beta_ngm = max(abs(eigenvalues$values))
  return(beta_ngm)
}

Run Metapopulation Model

#Collect parameters
parms_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_matrix[i,i] = within_pop_contact*beta*(1/parms_meta$gamma)
    parms_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_matrix[j,i] = between_pop_contact*beta*(1/parms_meta$gamma)
    nextgen_matrix[i,j] = between_pop_contact*beta*(1/parms_meta$gamma)
    parms_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_matrix[j,j] = within_pop_contact*beta*(1/parms_meta$gamma)
    beta_matrix[i,i] = within_pop_contact*beta
    beta_matrix[j,i] = between_pop_contact*beta
    beta_matrix[i,j] = between_pop_contact*beta
    beta_matrix[j,j] = within_pop_contact*beta
  }
  parms_meta[[paste0("N", i)]] = patchPopSize[i]
}
# Run simulations with the Direct method
set.seed(25)
out_meta <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_meta <- out_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta <- ggplot(data = plot_data_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 1, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_meta

ggsave(filename = "meta_plot_7.pdf", 
       plot = plot_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
## Table showing extinction/transmission info for each patch

extinct_data_meta <- out_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_meta
beta_meta <- beta.ngm(beta_matrix)
paste0("Beta for whole system = ", beta_meta)


R0_meta <- R0ngm(nextgen_matrix)
paste0("R0 = ", R0_meta)


paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_meta$count))
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_meta <- as_tibble(out_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
if (sim_endpoint_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta <- list()
sim_list_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
  }
))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_meta <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta <- out_100_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta[[i]] <- sim_data_meta
}

sim_output_meta <- bind_rows(sim_list_meta)
# Summary table of endpoint data
sim_output_meta <- sim_output_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta
# Make Summary Table of output
sim_summary_meta <- sim_output_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_meta

Varying waining immunity

0 Days

#Collect parameters
parms_meta_0 <- parms_meta
parms_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_meta_0 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_0 <- out_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_0 <- ggplot(data = plot_data_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_0 <- list()
sim_list_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_0 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_0 <- out_100_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_0[[i]] <- sim_data_meta_0
}

sim_output_meta_0 <- bind_rows(sim_list_meta_0)
# Summary table of endpoint data
sim_output_meta_0 <- sim_output_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_0

# Make Summary Table of output
sim_summary_meta_0 <- sim_output_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_meta_0

1 Day

#Collect parameters
parms_meta_1 <- parms_meta
parms_meta_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_meta_1 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_1 <- out_meta_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_1 <- ggplot(data = plot_data_meta_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_1
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_1 <- list()
sim_list_meta_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_1 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_1 <- out_100_meta_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_1[[i]] <- sim_data_meta_1
}

sim_output_meta_1 <- bind_rows(sim_list_meta_1)
# Summary table of endpoint data
sim_output_meta_1 <- sim_output_meta_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_1

# Make Summary Table of output
sim_summary_meta_1 <- sim_output_meta_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_meta_1

3 Days

#Collect parameters
parms_meta_3 <- parms_meta
parms_meta_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_meta_3 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_3 <- out_meta_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_3 <- ggplot(data = plot_data_meta_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_3
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_3 <- list()
sim_list_meta_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_3 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_3 <- out_100_meta_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_3[[i]] <- sim_data_meta_3
}

sim_output_meta_3 <- bind_rows(sim_list_meta_3)
# Summary table of endpoint data
sim_output_meta_3 <- sim_output_meta_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_3

# Make Summary Table of output
sim_summary_meta_3 <- sim_output_meta_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_meta_3

7 Days

#Collect parameters
parms_meta_7 <- parms_meta
parms_meta_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_meta_7 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_7 <- out_meta_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_7 <- ggplot(data = plot_data_meta_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_7
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_7 <- list()
sim_list_meta_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_7 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_7 <- out_100_meta_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_7[[i]] <- sim_data_meta_7
}

sim_output_meta_7 <- bind_rows(sim_list_meta_7)
# Summary table of endpoint data
sim_output_meta_7 <- sim_output_meta_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_7

# Make Summary Table of output
sim_summary_meta_7 <- sim_output_meta_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_meta_7

10 Days

#Collect parameters
parms_meta_10 <- parms_meta
parms_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_meta_10 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_10 <- out_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_10 <- ggplot(data = plot_data_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_10 <- list()
sim_list_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_10 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_10 <- out_100_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_10[[i]] <- sim_data_meta_10
}

sim_output_meta_10 <- bind_rows(sim_list_meta_10)
# Summary table of endpoint data
sim_output_meta_10 <- sim_output_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_meta_10 <- sim_output_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/14)
sim_summary_meta_10

20 Days

#Collect parameters
parms_meta_20 <- parms_meta
parms_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_meta_20 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_20 <- out_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_20 <- ggplot(data = plot_data_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_20 <- list()
sim_list_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_20 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_20 <- out_100_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_20[[i]] <- sim_data_meta_20
}

sim_output_meta_20 <- bind_rows(sim_list_meta_20)
# Summary table of endpoint data
sim_output_meta_20 <- sim_output_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_20

# Make Summary Table of output
sim_summary_meta_20 <- sim_output_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_meta_20

30 Days

#Collect parameters
parms_meta_30 <- parms_meta
parms_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_meta_30 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_30 <- out_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_30 <- ggplot(data = plot_data_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_30 <- list()
sim_list_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_30 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_30 <- out_100_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_30[[i]] <- sim_data_meta_30
}

sim_output_meta_30 <- bind_rows(sim_list_meta_30)
# Summary table of endpoint data
sim_output_meta_30 <- sim_output_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_30

# Make Summary Table of output
sim_summary_meta_30 <- sim_output_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_meta_30

40 Days

#Collect parameters
parms_meta_40 <- parms_meta
parms_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_meta_40 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_40 <- out_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_40 <- ggplot(data = plot_data_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_40 <- list()
sim_list_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_40 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_40 <- out_100_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_40[[i]] <- sim_data_meta_40
}

sim_output_meta_40 <- bind_rows(sim_list_meta_40)
# Summary table of endpoint data
sim_output_meta_40 <- sim_output_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_40

# Make Summary Table of output
sim_summary_meta_40 <- sim_output_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_meta_40

50 Days

#Collect parameters
parms_meta_50 <- parms_meta
parms_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_meta_50 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_50 <- out_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_50 <- ggplot(data = plot_data_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_50 <- list()
sim_list_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_50 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_50 <- out_100_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_50[[i]] <- sim_data_meta_50
}

sim_output_meta_50 <- bind_rows(sim_list_meta_50)
# Summary table of endpoint data
sim_output_meta_50 <- sim_output_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_50

# Make Summary Table of output
sim_summary_meta_50 <- sim_output_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_meta_50

60 Days

#Collect parameters
parms_meta_60 <- parms_meta
parms_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_meta_60 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_60 <- out_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_60 <- ggplot(data = plot_data_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_60 <- list()
sim_list_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_60 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_60 <- out_100_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_60[[i]] <- sim_data_meta_60
}

sim_output_meta_60 <- bind_rows(sim_list_meta_60)
# Summary table of endpoint data
sim_output_meta_60 <- sim_output_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_60

# Make Summary Table of output
sim_summary_meta_60 <- sim_output_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_meta_60

70 Days

#Collect parameters
parms_meta_70 <- parms_meta
parms_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_meta_70 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_70 <- out_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_70 <- ggplot(data = plot_data_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_70 <- list()
sim_list_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_70 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_70 <- out_100_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_70[[i]] <- sim_data_meta_70
}

sim_output_meta_70 <- bind_rows(sim_list_meta_70)
# Summary table of endpoint data
sim_output_meta_70 <- sim_output_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_70

# Make Summary Table of output
sim_summary_meta_70 <- sim_output_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_meta_70

80 Days

#Collect parameters
parms_meta_80 <- parms_meta
parms_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_meta_80 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_80 <- out_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_80 <- ggplot(data = plot_data_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_80 <- list()
sim_list_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_80 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_80 <- out_100_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_80[[i]] <- sim_data_meta_80
}

sim_output_meta_80 <- bind_rows(sim_list_meta_80)
# Summary table of endpoint data
sim_output_meta_80 <- sim_output_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_80

# Make Summary Table of output
sim_summary_meta_80 <- sim_output_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_meta_80

90 Days

#Collect parameters
parms_meta_90 <- parms_meta
parms_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_meta_90 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_90 <- out_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_90 <- ggplot(data = plot_data_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_90
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_90 <- list()
sim_list_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_90 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_90 <- out_100_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_90[[i]] <- sim_data_meta_90
}

sim_output_meta_90 <- bind_rows(sim_list_meta_90)
# Summary table of endpoint data
sim_output_meta_90 <- sim_output_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_90

# Make Summary Table of output
sim_summary_meta_90 <- sim_output_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_meta_90

180 Days

#Collect parameters
parms_meta_180 <- parms_meta
parms_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_meta_180 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_180 <- out_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_180 <- ggplot(data = plot_data_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_180 <- list()
sim_list_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_180 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_180 <- out_100_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_180[[i]] <- sim_data_meta_180
}

sim_output_meta_180 <- bind_rows(sim_list_meta_180)
# Summary table of endpoint data
sim_output_meta_180 <- sim_output_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_180

# Make Summary Table of output
sim_summary_meta_180 <- sim_output_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_meta_180

110 Days

#Collect parameters
parms_meta_110 <- parms_meta
parms_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_meta_110 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_110 <- out_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_110 <- ggplot(data = plot_data_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_110
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_110 <- list()
sim_list_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_110 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_110 <- out_100_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_110[[i]] <- sim_data_meta_110
}

sim_output_meta_110 <- bind_rows(sim_list_meta_110)
# Summary table of endpoint data
sim_output_meta_110 <- sim_output_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_110

# Make Summary Table of output
sim_summary_meta_110 <- sim_output_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_meta_110

120 Days

#Collect parameters
parms_meta_120 <- parms_meta
parms_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_meta_120 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_120 <- out_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_120 <- ggplot(data = plot_data_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_120
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_120 <- list()
sim_list_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_120 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_120 <- out_100_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_120[[i]] <- sim_data_meta_120
}

sim_output_meta_120 <- bind_rows(sim_list_meta_120)
# Summary table of endpoint data
sim_output_meta_120 <- sim_output_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_120

# Make Summary Table of output
sim_summary_meta_120 <- sim_output_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_meta_120

130 Days

#Collect parameters
parms_meta_130 <- parms_meta
parms_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_meta_130 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_130 <- out_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_130 <- ggplot(data = plot_data_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_130
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_130 <- list()
sim_list_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_130 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_130 <- out_100_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_130[[i]] <- sim_data_meta_130
}

sim_output_meta_130 <- bind_rows(sim_list_meta_130)
# Summary table of endpoint data
sim_output_meta_130 <- sim_output_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_130

# Make Summary Table of output
sim_summary_meta_130 <- sim_output_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_meta_130

150 Days

#Collect parameters
parms_meta_150 <- parms_meta
parms_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_meta_150 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_150 <- out_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_150 <- ggplot(data = plot_data_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_150 <- list()
sim_list_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_150 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_150 <- out_100_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_150[[i]] <- sim_data_meta_150
}

sim_output_meta_150 <- bind_rows(sim_list_meta_150)
# Summary table of endpoint data
sim_output_meta_150 <- sim_output_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_150

# Make Summary Table of output
sim_summary_meta_150 <- sim_output_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_meta_150

220 Days

#Collect parameters
parms_meta_220 <- parms_meta
parms_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_meta_220 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_220 <- out_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_220 <- ggplot(data = plot_data_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_220
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_220 <- list()
sim_list_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_220 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_220 <- out_100_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_220[[i]] <- sim_data_meta_220
}

sim_output_meta_220 <- bind_rows(sim_list_meta_220)
# Summary table of endpoint data
sim_output_meta_220 <- sim_output_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_220

# Make Summary Table of output
sim_summary_meta_220 <- sim_output_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_meta_220

270 Days

#Collect parameters
parms_meta_270 <- parms_meta
parms_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_meta_270 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_270 <- out_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_270 <- ggplot(data = plot_data_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_270
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_270 <- list()
sim_list_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_270 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_270 <- out_100_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_270[[i]] <- sim_data_meta_270
}

sim_output_meta_270 <- bind_rows(sim_list_meta_270)
# Summary table of endpoint data
sim_output_meta_270 <- sim_output_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_270

# Make Summary Table of output
sim_summary_meta_270 <- sim_output_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_meta_270

365 Days

#Collect parameters
parms_meta_365 <- parms_meta
parms_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_meta_365 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_365 <- out_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_365 <- ggplot(data = plot_data_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_365 <- list()
sim_list_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_365 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_365 <- out_100_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_365[[i]] <- sim_data_meta_365
}

sim_output_meta_365 <- bind_rows(sim_list_meta_365)
# Summary table of endpoint data
sim_output_meta_365 <- sim_output_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_365

# Make Summary Table of output
sim_summary_meta_365 <- sim_output_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_meta_365

Single

Results

waning_results_7 <- sim_summary_meta %>%
  bind_rows(sim_summary_meta_3) %>%
  bind_rows(sim_summary_meta_7) %>%
  bind_rows(sim_summary_meta_10) %>%
  bind_rows(sim_summary_meta_20) %>%
  bind_rows(sim_summary_meta_30) %>%
  bind_rows(sim_summary_meta_40) %>%
  bind_rows(sim_summary_meta_50) %>%
  bind_rows(sim_summary_meta_60) %>%
  bind_rows(sim_summary_meta_70) %>%
  bind_rows(sim_summary_meta_80) %>%
  bind_rows(sim_summary_meta_90) %>%
  bind_rows(sim_summary_meta_100) %>%
  bind_rows(sim_summary_meta_110) %>%
  bind_rows(sim_summary_meta_120) %>%
  bind_rows(sim_summary_meta_130) %>%
  bind_rows(sim_summary_meta_150) %>%
  bind_rows(sim_summary_meta_220) %>%
  bind_rows(sim_summary_meta_270) %>%
  bind_rows(sim_summary_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 7)

write_csv(waning_results_7, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_7.csv")

waning_results_7
ggplot(waning_results_7, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

3-Patch Metapopulation Model

The same metapopulation SEIRS model was then used to model the dynamics of persistence in a 3-patch system and understand the effect of waning immunity.

###Set-up

# Define Paramenters
patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Patch size
U <- length(patchPopSize_3)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_3_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize_3[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize_3[i])
  }
))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_3_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_3_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Run Metapopulation Model

#Collect parameters
parms_3_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_3_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_3_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_3_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_3_matrix[i,i] = within_pop_contact*beta*(1/parms_3_meta$gamma)
    parms_3_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_3_matrix[j,i] = between_pop_contact*beta*(1/parms_3_meta$gamma)
    nextgen_3_matrix[i,j] = between_pop_contact*beta*(1/parms_3_meta$gamma)
    parms_3_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_3_matrix[j,j] = within_pop_contact*beta*(1/parms_3_meta$gamma)
    beta_3_matrix[i,i] = within_pop_contact*beta
    beta_3_matrix[j,i] = between_pop_contact*beta
    beta_3_matrix[i,j] = between_pop_contact*beta
    beta_3_matrix[j,j] = within_pop_contact*beta
  }
  parms_3_meta[[paste0("N", i)]] = patchPopSize_3[i]
}
# Run simulations with the Direct method
set.seed(25)
out_3_meta <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_3_meta <- out_3_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta <- ggplot(data = plot_data_3_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 1, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_3_meta

ggsave(filename = "meta_plot_3.pdf", 
       plot = plot_3_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
## Table showing extinction/transmission info for each patch

extinct_data_3_meta <- out_3_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_3_meta
beta_3_meta <- beta.ngm(beta_3_matrix)
paste0("Beta for whole system = ", beta_3_meta)


R0_3_meta <- R0ngm(nextgen_3_matrix)
paste0("R0 = ", R0_3_meta)


paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_3_meta$count))
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_3_meta <- as_tibble(out_3_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
if (sim_endpoint_3_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta <- list()
sim_list_3_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
  }
))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_3_meta <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta <- out_100_3_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta[[i]] <- sim_data_3_meta
}

sim_output_3_meta <- bind_rows(sim_list_3_meta)
# Summary table of endpoint data
sim_output_3_meta <- sim_output_3_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta
# Make Summary Table of output
sim_summary_3_meta <- sim_output_3_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_3_meta

Varying waining immunity

0 Days

#Collect parameters
parms_3_meta_0 <- parms_3_meta
parms_3_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_3_meta_0 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_0 <- out_3_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_0 <- ggplot(data = plot_data_3_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_0 <- list()
sim_list_3_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_0 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_0 <- out_100_3_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_0[[i]] <- sim_data_3_meta_0
}

sim_output_3_meta_0 <- bind_rows(sim_list_3_meta_0)
# Summary table of endpoint data
sim_output_3_meta_0 <- sim_output_3_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_0

# Make Summary Table of output
sim_summary_3_meta_0 <- sim_output_3_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_3_meta_0

1 Day

#Collect parameters
parms_3_meta_1 <- parms_3_meta
parms_3_meta_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_3_meta_1 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_1 <- out_3_meta_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_1 <- ggplot(data = plot_data_3_meta_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_1
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_1 <- list()
sim_list_3_meta_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_1 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_1 <- out_100_3_meta_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_1[[i]] <- sim_data_3_meta_1
}

sim_output_3_meta_1 <- bind_rows(sim_list_3_meta_1)
# Summary table of endpoint data
sim_output_3_meta_1 <- sim_output_3_meta_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_1

# Make Summary Table of output
sim_summary_3_meta_1 <- sim_output_3_meta_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_3_meta_1

3 Days

#Collect parameters
parms_3_meta_3 <- parms_3_meta
parms_3_meta_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_3_meta_3 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_3 <- out_3_meta_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_3 <- ggplot(data = plot_data_3_meta_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_3
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_3 <- list()
sim_list_3_meta_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_3 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_3 <- out_100_3_meta_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_3[[i]] <- sim_data_3_meta_3
}

sim_output_3_meta_3 <- bind_rows(sim_list_3_meta_3)
# Summary table of endpoint data
sim_output_3_meta_3 <- sim_output_3_meta_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_3

# Make Summary Table of output
sim_summary_3_meta_3 <- sim_output_3_meta_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3_meta_3

7 Days

#Collect parameters
parms_3_meta_7 <- parms_3_meta
parms_3_meta_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_3_meta_7 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_7 <- out_3_meta_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_7 <- ggplot(data = plot_data_3_meta_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_7
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_7 <- list()
sim_list_3_meta_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_7 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_7 <- out_100_3_meta_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_7[[i]] <- sim_data_3_meta_7
}

sim_output_3_meta_7 <- bind_rows(sim_list_3_meta_7)
# Summary table of endpoint data
sim_output_3_meta_7 <- sim_output_3_meta_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_7

# Make Summary Table of output
sim_summary_3_meta_7 <- sim_output_3_meta_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_3_meta_7

10 Days

#Collect parameters
parms_3_meta_10 <- parms_3_meta
parms_3_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_3_meta_10 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_10 <- out_3_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_10 <- ggplot(data = plot_data_3_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_10 <- list()
sim_list_3_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_10 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_10 <- out_100_3_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_10[[i]] <- sim_data_3_meta_10
}

sim_output_3_meta_10 <- bind_rows(sim_list_3_meta_10)
# Summary table of endpoint data
sim_output_3_meta_10 <- sim_output_3_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_3_meta_10 <- sim_output_3_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/14)
sim_summary_3_meta_10

20 Days

#Collect parameters
parms_3_meta_20 <- parms_3_meta
parms_3_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_3_meta_20 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_20 <- out_3_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_20 <- ggplot(data = plot_data_3_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_20 <- list()
sim_list_3_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_20 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_20 <- out_100_3_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_20[[i]] <- sim_data_3_meta_20
}

sim_output_3_meta_20 <- bind_rows(sim_list_3_meta_20)
# Summary table of endpoint data
sim_output_3_meta_20 <- sim_output_3_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_20

# Make Summary Table of output
sim_summary_3_meta_20 <- sim_output_3_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_3_meta_20

30 Days

#Collect parameters
parms_3_meta_30 <- parms_3_meta
parms_3_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_3_meta_30 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_30 <- out_3_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_30 <- ggplot(data = plot_data_3_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_30 <- list()
sim_list_3_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_30 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_30 <- out_100_3_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_30[[i]] <- sim_data_3_meta_30
}

sim_output_3_meta_30 <- bind_rows(sim_list_3_meta_30)
# Summary table of endpoint data
sim_output_3_meta_30 <- sim_output_3_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_30

# Make Summary Table of output
sim_summary_3_meta_30 <- sim_output_3_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_3_meta_30

40 Days

#Collect parameters
parms_3_meta_40 <- parms_3_meta
parms_3_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_3_meta_40 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_40 <- out_3_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_40 <- ggplot(data = plot_data_3_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_40 <- list()
sim_list_3_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_40 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_40 <- out_100_3_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_40[[i]] <- sim_data_3_meta_40
}

sim_output_3_meta_40 <- bind_rows(sim_list_3_meta_40)
# Summary table of endpoint data
sim_output_3_meta_40 <- sim_output_3_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_40

# Make Summary Table of output
sim_summary_3_meta_40 <- sim_output_3_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_3_meta_40

50 Days

#Collect parameters
parms_3_meta_50 <- parms_3_meta
parms_3_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_3_meta_50 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_50 <- out_3_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_50 <- ggplot(data = plot_data_3_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_50 <- list()
sim_list_3_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_50 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_50 <- out_100_3_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_50[[i]] <- sim_data_3_meta_50
}

sim_output_3_meta_50 <- bind_rows(sim_list_3_meta_50)
# Summary table of endpoint data
sim_output_3_meta_50 <- sim_output_3_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_50

# Make Summary Table of output
sim_summary_3_meta_50 <- sim_output_3_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_3_meta_50

60 Days

#Collect parameters
parms_3_meta_60 <- parms_3_meta
parms_3_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_3_meta_60 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_60 <- out_3_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_60 <- ggplot(data = plot_data_3_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_60 <- list()
sim_list_3_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_60 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_60 <- out_100_3_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_60[[i]] <- sim_data_3_meta_60
}

sim_output_3_meta_60 <- bind_rows(sim_list_3_meta_60)
# Summary table of endpoint data
sim_output_3_meta_60 <- sim_output_3_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_60

# Make Summary Table of output
sim_summary_3_meta_60 <- sim_output_3_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_3_meta_60

70 Days

#Collect parameters
parms_3_meta_70 <- parms_3_meta
parms_3_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_3_meta_70 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_70 <- out_3_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_70 <- ggplot(data = plot_data_3_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_70 <- list()
sim_list_3_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_70 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_70 <- out_100_3_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_70[[i]] <- sim_data_3_meta_70
}

sim_output_3_meta_70 <- bind_rows(sim_list_3_meta_70)
# Summary table of endpoint data
sim_output_3_meta_70 <- sim_output_3_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_70

# Make Summary Table of output
sim_summary_3_meta_70 <- sim_output_3_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_3_meta_70

80 Days

#Collect parameters
parms_3_meta_80 <- parms_3_meta
parms_3_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_3_meta_80 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_80 <- out_3_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_80 <- ggplot(data = plot_data_3_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_80 <- list()
sim_list_3_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_80 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_80 <- out_100_3_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_80[[i]] <- sim_data_3_meta_80
}

sim_output_3_meta_80 <- bind_rows(sim_list_3_meta_80)
# Summary table of endpoint data
sim_output_3_meta_80 <- sim_output_3_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_80

# Make Summary Table of output
sim_summary_3_meta_80 <- sim_output_3_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_3_meta_80

90 Days

#Collect parameters
parms_3_meta_90 <- parms_3_meta
parms_3_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_3_meta_90 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_90 <- out_3_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_90 <- ggplot(data = plot_data_3_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_90
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_90 <- list()
sim_list_3_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_90 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_90 <- out_100_3_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_90[[i]] <- sim_data_3_meta_90
}

sim_output_3_meta_90 <- bind_rows(sim_list_3_meta_90)
# Summary table of endpoint data
sim_output_3_meta_90 <- sim_output_3_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_90

# Make Summary Table of output
sim_summary_3_meta_90 <- sim_output_3_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_3_meta_90

180 Days

#Collect parameters
parms_3_meta_180 <- parms_3_meta
parms_3_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_3_meta_180 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_180 <- out_3_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_180 <- ggplot(data = plot_data_3_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_180 <- list()
sim_list_3_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_180 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_180 <- out_100_3_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_180[[i]] <- sim_data_3_meta_180
}

sim_output_3_meta_180 <- bind_rows(sim_list_3_meta_180)
# Summary table of endpoint data
sim_output_3_meta_180 <- sim_output_3_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_180

# Make Summary Table of output
sim_summary_3_meta_180 <- sim_output_3_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_3_meta_180

110 Days

#Collect parameters
parms_3_meta_110 <- parms_3_meta
parms_3_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_3_meta_110 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_110 <- out_3_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_110 <- ggplot(data = plot_data_3_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_110
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_110 <- list()
sim_list_3_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_110 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_110 <- out_100_3_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_110[[i]] <- sim_data_3_meta_110
}

sim_output_3_meta_110 <- bind_rows(sim_list_3_meta_110)
# Summary table of endpoint data
sim_output_3_meta_110 <- sim_output_3_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_110

# Make Summary Table of output
sim_summary_3_meta_110 <- sim_output_3_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_3_meta_110

120 Days

#Collect parameters
parms_3_meta_120 <- parms_3_meta
parms_3_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_3_meta_120 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_120 <- out_3_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_120 <- ggplot(data = plot_data_3_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_120
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_120 <- list()
sim_list_3_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_120 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_120 <- out_100_3_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_120[[i]] <- sim_data_3_meta_120
}

sim_output_3_meta_120 <- bind_rows(sim_list_3_meta_120)
# Summary table of endpoint data
sim_output_3_meta_120 <- sim_output_3_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_120

# Make Summary Table of output
sim_summary_3_meta_120 <- sim_output_3_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_3_meta_120

130 Days

#Collect parameters
parms_3_meta_130 <- parms_3_meta
parms_3_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_3_meta_130 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_130 <- out_3_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_130 <- ggplot(data = plot_data_3_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_130
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_130 <- list()
sim_list_3_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_130 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_130 <- out_100_3_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_130[[i]] <- sim_data_3_meta_130
}

sim_output_3_meta_130 <- bind_rows(sim_list_3_meta_130)
# Summary table of endpoint data
sim_output_3_meta_130 <- sim_output_3_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_130

# Make Summary Table of output
sim_summary_3_meta_130 <- sim_output_3_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_3_meta_130

150 Days

#Collect parameters
parms_3_meta_150 <- parms_3_meta
parms_3_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_3_meta_150 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_150 <- out_3_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_150 <- ggplot(data = plot_data_3_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_150 <- list()
sim_list_3_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_150 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_150 <- out_100_3_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_150[[i]] <- sim_data_3_meta_150
}

sim_output_3_meta_150 <- bind_rows(sim_list_3_meta_150)
# Summary table of endpoint data
sim_output_3_meta_150 <- sim_output_3_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_150

# Make Summary Table of output
sim_summary_3_meta_150 <- sim_output_3_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_3_meta_150

220 Days

#Collect parameters
parms_3_meta_220 <- parms_3_meta
parms_3_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_3_meta_220 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_220 <- out_3_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_220 <- ggplot(data = plot_data_3_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_220
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_220 <- list()
sim_list_3_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_220 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_220 <- out_100_3_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_220[[i]] <- sim_data_3_meta_220
}

sim_output_3_meta_220 <- bind_rows(sim_list_3_meta_220)
# Summary table of endpoint data
sim_output_3_meta_220 <- sim_output_3_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_220

# Make Summary Table of output
sim_summary_3_meta_220 <- sim_output_3_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_3_meta_220

270 Days

#Collect parameters
parms_3_meta_270 <- parms_3_meta
parms_3_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_3_meta_270 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_270 <- out_3_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_270 <- ggplot(data = plot_data_3_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_270
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_270 <- list()
sim_list_3_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_270 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_270 <- out_100_3_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_270[[i]] <- sim_data_3_meta_270
}

sim_output_3_meta_270 <- bind_rows(sim_list_3_meta_270)
# Summary table of endpoint data
sim_output_3_meta_270 <- sim_output_3_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_270

# Make Summary Table of output
sim_summary_3_meta_270 <- sim_output_3_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_3_meta_270

365 Days

#Collect parameters
parms_3_meta_365 <- parms_3_meta
parms_3_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_3_meta_365 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_365 <- out_3_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_365 <- ggplot(data = plot_data_3_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_365 <- list()
sim_list_3_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_365 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_365 <- out_100_3_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_365[[i]] <- sim_data_3_meta_365
}

sim_output_3_meta_365 <- bind_rows(sim_list_3_meta_365)
# Summary table of endpoint data
sim_output_3_meta_365 <- sim_output_3_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_365

# Make Summary Table of output
sim_summary_3_meta_365 <- sim_output_3_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_3_meta_365

Results

waning_results_3 <- sim_summary_3_meta %>%
  bind_rows(sim_summary_3_meta_3) %>%
  bind_rows(sim_summary_3_meta_7) %>%
  bind_rows(sim_summary_3_meta_10) %>%
  bind_rows(sim_summary_3_meta_20) %>%
  bind_rows(sim_summary_3_meta_30) %>%
  bind_rows(sim_summary_3_meta_40) %>%
  bind_rows(sim_summary_3_meta_50) %>%
  bind_rows(sim_summary_3_meta_60) %>%
  bind_rows(sim_summary_3_meta_70) %>%
  bind_rows(sim_summary_3_meta_80) %>%
  bind_rows(sim_summary_3_meta_90) %>%
  bind_rows(sim_summary_3_meta_180) %>%
  bind_rows(sim_summary_3_meta_110) %>%
  bind_rows(sim_summary_3_meta_120) %>%
  bind_rows(sim_summary_3_meta_130) %>%
  bind_rows(sim_summary_3_meta_150) %>%
  bind_rows(sim_summary_3_meta_220) %>%
  bind_rows(sim_summary_3_meta_270) %>%
  bind_rows(sim_summary_3_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 3)

write_csv(waning_results_3, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_3.csv")

waning_results_3
ggplot(waning_results_3, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

14 Metapopulation Model

The same metapopulation SEIRS model was then used to model the dynamics of persistence in a 14-patch system and understand the effect of waning immunity.

###Set-up

# Define Paramenters
patchPopSize_14 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Patch size
U <- length(patchPopSize_14)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_14_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize_14[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize_14[i])
  }
))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_14_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_14_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Run Metapopulation Model

#Collect parameters
parms_14_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_14_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_14_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_14_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_14_matrix[i,i] = within_pop_contact*beta*(1/parms_14_meta$gamma)
    parms_14_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_14_matrix[j,i] = between_pop_contact*beta*(1/parms_14_meta$gamma)
    nextgen_14_matrix[i,j] = between_pop_contact*beta*(1/parms_14_meta$gamma)
    parms_14_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_14_matrix[j,j] = within_pop_contact*beta*(1/parms_14_meta$gamma)
    beta_14_matrix[i,i] = within_pop_contact*beta
    beta_14_matrix[j,i] = between_pop_contact*beta
    beta_14_matrix[i,j] = between_pop_contact*beta
    beta_14_matrix[j,j] = within_pop_contact*beta
  }
  parms_14_meta[[paste0("N", i)]] = patchPopSize_14[i]
}
# Run simulations with the Direct method
set.seed(25)
out_14_meta <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_14_meta <- out_14_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta <- ggplot(data = plot_data_14_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_14_meta

ggsave(filename = "meta_14_plot.pdf", 
       plot = plot_14_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
## Table showing extinction/transmission info for each patch

extinct_data_14_meta <- out_14_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_14_meta
beta_14_meta <- beta.ngm(beta_14_matrix)
paste0("Beta for whole system = ", beta_14_meta)


R0_14_meta <- R0ngm(nextgen_14_matrix)
paste0("R0 = ", R0_14_meta)


paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_14_meta$count))
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_14_meta <- as_tibble(out_14_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
if (sim_endpoint_14_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta <- list()
sim_list_14_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_14 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize_14[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_14[x])
  }
))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_14_meta <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta <- out_100_14_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta[[i]] <- sim_data_14_meta
}

sim_output_14_meta <- bind_rows(sim_list_14_meta)
# Summary table of endpoint data
sim_output_14_meta <- sim_output_14_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta
# Make Summary Table of output
sim_summary_14_meta <- sim_output_14_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_14_meta

Varying waining immunity

0 Days

#Collect parameters
parms_14_meta_0 <- parms_14_meta
parms_14_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_14_meta_0 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_0 <- out_14_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_0 <- ggplot(data = plot_data_14_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_0 <- list()
sim_list_14_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_0 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_0 <- out_100_14_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_0[[i]] <- sim_data_14_meta_0
}

sim_output_14_meta_0 <- bind_rows(sim_list_14_meta_0)
# Summary table of endpoint data
sim_output_14_meta_0 <- sim_output_14_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_0

# Make Summary Table of output
sim_summary_14_meta_0 <- sim_output_14_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_14_meta_0

10 Days

#Collect parameters
parms_14_meta_10 <- parms_14_meta
parms_14_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_14_meta_10 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_10 <- out_14_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_10 <- ggplot(data = plot_data_14_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_10 <- list()
sim_list_14_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_10 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_10 <- out_100_14_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_10[[i]] <- sim_data_14_meta_10
}

sim_output_14_meta_10 <- bind_rows(sim_list_14_meta_10)
# Summary table of endpoint data
sim_output_14_meta_10 <- sim_output_14_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_14_meta_10 <- sim_output_14_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_14_meta_10

20 Days

#Collect parameters
parms_14_meta_20 <- parms_14_meta
parms_14_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_14_meta_20 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_20 <- out_14_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_20 <- ggplot(data = plot_data_14_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_20 <- list()
sim_list_14_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_20 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_20 <- out_100_14_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_20[[i]] <- sim_data_14_meta_20
}

sim_output_14_meta_20 <- bind_rows(sim_list_14_meta_20)
# Summary table of endpoint data
sim_output_14_meta_20 <- sim_output_14_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_20

# Make Summary Table of output
sim_summary_14_meta_20 <- sim_output_14_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_14_meta_20

30 Days

#Collect parameters
parms_14_meta_30 <- parms_14_meta
parms_14_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_14_meta_30 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_30 <- out_14_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_30 <- ggplot(data = plot_data_14_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_30 <- list()
sim_list_14_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_30 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_30 <- out_100_14_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_30[[i]] <- sim_data_14_meta_30
}

sim_output_14_meta_30 <- bind_rows(sim_list_14_meta_30)
# Summary table of endpoint data
sim_output_14_meta_30 <- sim_output_14_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_30

# Make Summary Table of output
sim_summary_14_meta_30 <- sim_output_14_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_14_meta_30

40 Days

#Collect parameters
parms_14_meta_40 <- parms_14_meta
parms_14_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_14_meta_40 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_40 <- out_14_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_40 <- ggplot(data = plot_data_14_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_40 <- list()
sim_list_14_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_40 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_40 <- out_100_14_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_40[[i]] <- sim_data_14_meta_40
}

sim_output_14_meta_40 <- bind_rows(sim_list_14_meta_40)
# Summary table of endpoint data
sim_output_14_meta_40 <- sim_output_14_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_40

# Make Summary Table of output
sim_summary_14_meta_40 <- sim_output_14_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_14_meta_40

50 Days

#Collect parameters
parms_14_meta_50 <- parms_14_meta
parms_14_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_14_meta_50 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_50 <- out_14_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_50 <- ggplot(data = plot_data_14_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_50 <- list()
sim_list_14_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_50 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_50 <- out_100_14_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_50[[i]] <- sim_data_14_meta_50
}

sim_output_14_meta_50 <- bind_rows(sim_list_14_meta_50)
# Summary table of endpoint data
sim_output_14_meta_50 <- sim_output_14_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_50

# Make Summary Table of output
sim_summary_14_meta_50 <- sim_output_14_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_14_meta_50

60 Days

#Collect parameters
parms_14_meta_60 <- parms_14_meta
parms_14_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_14_meta_60 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_60 <- out_14_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_60 <- ggplot(data = plot_data_14_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_60 <- list()
sim_list_14_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_60 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_60 <- out_100_14_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_60[[i]] <- sim_data_14_meta_60
}

sim_output_14_meta_60 <- bind_rows(sim_list_14_meta_60)
# Summary table of endpoint data
sim_output_14_meta_60 <- sim_output_14_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_60

# Make Summary Table of output
sim_summary_14_meta_60 <- sim_output_14_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_14_meta_60

70 Days

#Collect parameters
parms_14_meta_70 <- parms_14_meta
parms_14_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_14_meta_70 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_70 <- out_14_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_70 <- ggplot(data = plot_data_14_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_70 <- list()
sim_list_14_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_70 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_70 <- out_100_14_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_70[[i]] <- sim_data_14_meta_70
}

sim_output_14_meta_70 <- bind_rows(sim_list_14_meta_70)
# Summary table of endpoint data
sim_output_14_meta_70 <- sim_output_14_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_70

# Make Summary Table of output
sim_summary_14_meta_70 <- sim_output_14_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_14_meta_70

80 Days

#Collect parameters
parms_14_meta_80 <- parms_14_meta
parms_14_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_14_meta_80 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_80 <- out_14_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_80 <- ggplot(data = plot_data_14_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_80 <- list()
sim_list_14_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_80 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_80 <- out_100_14_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_80[[i]] <- sim_data_14_meta_80
}

sim_output_14_meta_80 <- bind_rows(sim_list_14_meta_80)
# Summary table of endpoint data
sim_output_14_meta_80 <- sim_output_14_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_80

# Make Summary Table of output
sim_summary_14_meta_80 <- sim_output_14_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_14_meta_80

90 Days

#Collect parameters
parms_14_meta_90 <- parms_14_meta
parms_14_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_14_meta_90 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_90 <- out_14_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_90 <- ggplot(data = plot_data_14_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_90
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_90 <- list()
sim_list_14_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_90 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_90 <- out_100_14_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_90[[i]] <- sim_data_14_meta_90
}

sim_output_14_meta_90 <- bind_rows(sim_list_14_meta_90)
# Summary table of endpoint data
sim_output_14_meta_90 <- sim_output_14_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_90

# Make Summary Table of output
sim_summary_14_meta_90 <- sim_output_14_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_14_meta_90

180 Days

#Collect parameters
parms_14_meta_180 <- parms_14_meta
parms_14_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_14_meta_180 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_180 <- out_14_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_180 <- ggplot(data = plot_data_14_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_180 <- list()
sim_list_14_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_180 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_180 <- out_100_14_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_180[[i]] <- sim_data_14_meta_180
}

sim_output_14_meta_180 <- bind_rows(sim_list_14_meta_180)
# Summary table of endpoint data
sim_output_14_meta_180 <- sim_output_14_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_180

# Make Summary Table of output
sim_summary_14_meta_180 <- sim_output_14_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_14_meta_180

110 Days

#Collect parameters
parms_14_meta_110 <- parms_14_meta
parms_14_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_14_meta_110 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_110 <- out_14_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_110 <- ggplot(data = plot_data_14_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_110
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_110 <- list()
sim_list_14_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_110 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_110 <- out_100_14_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_110[[i]] <- sim_data_14_meta_110
}

sim_output_14_meta_110 <- bind_rows(sim_list_14_meta_110)
# Summary table of endpoint data
sim_output_14_meta_110 <- sim_output_14_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_110

# Make Summary Table of output
sim_summary_14_meta_110 <- sim_output_14_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_14_meta_110

120 Days

#Collect parameters
parms_14_meta_120 <- parms_14_meta
parms_14_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_14_meta_120 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_120 <- out_14_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_120 <- ggplot(data = plot_data_14_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_120
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_120 <- list()
sim_list_14_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_120 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_120 <- out_100_14_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_120[[i]] <- sim_data_14_meta_120
}

sim_output_14_meta_120 <- bind_rows(sim_list_14_meta_120)
# Summary table of endpoint data
sim_output_14_meta_120 <- sim_output_14_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_120

# Make Summary Table of output
sim_summary_14_meta_120 <- sim_output_14_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_14_meta_120

130 Days

#Collect parameters
parms_14_meta_130 <- parms_14_meta
parms_14_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_14_meta_130 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_130 <- out_14_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_130 <- ggplot(data = plot_data_14_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_130
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_130 <- list()
sim_list_14_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_130 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_130 <- out_100_14_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_130[[i]] <- sim_data_14_meta_130
}

sim_output_14_meta_130 <- bind_rows(sim_list_14_meta_130)
# Summary table of endpoint data
sim_output_14_meta_130 <- sim_output_14_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_130

# Make Summary Table of output
sim_summary_14_meta_130 <- sim_output_14_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_14_meta_130

150 Days

#Collect parameters
parms_14_meta_150 <- parms_14_meta
parms_14_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_14_meta_150 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_150 <- out_14_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_150 <- ggplot(data = plot_data_14_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_150 <- list()
sim_list_14_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_150 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_150 <- out_100_14_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_150[[i]] <- sim_data_14_meta_150
}

sim_output_14_meta_150 <- bind_rows(sim_list_14_meta_150)
# Summary table of endpoint data
sim_output_14_meta_150 <- sim_output_14_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_150

# Make Summary Table of output
sim_summary_14_meta_150 <- sim_output_14_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_14_meta_150

220 Days

#Collect parameters
parms_14_meta_220 <- parms_14_meta
parms_14_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_14_meta_220 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_220 <- out_14_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_220 <- ggplot(data = plot_data_14_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_220
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_220 <- list()
sim_list_14_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_220 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_220 <- out_100_14_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_220[[i]] <- sim_data_14_meta_220
}

sim_output_14_meta_220 <- bind_rows(sim_list_14_meta_220)
# Summary table of endpoint data
sim_output_14_meta_220 <- sim_output_14_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_220

# Make Summary Table of output
sim_summary_14_meta_220 <- sim_output_14_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_14_meta_220

270 Days

#Collect parameters
parms_14_meta_270 <- parms_14_meta
parms_14_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_14_meta_270 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_270 <- out_14_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_270 <- ggplot(data = plot_data_14_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_270
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_270 <- list()
sim_list_14_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_270 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_270 <- out_100_14_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_270[[i]] <- sim_data_14_meta_270
}

sim_output_14_meta_270 <- bind_rows(sim_list_14_meta_270)
# Summary table of endpoint data
sim_output_14_meta_270 <- sim_output_14_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_270

# Make Summary Table of output
sim_summary_14_meta_270 <- sim_output_14_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_14_meta_270

365 Days

#Collect parameters
parms_14_meta_365 <- parms_14_meta
parms_14_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_14_meta_365 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_365 <- out_14_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_365 <- ggplot(data = plot_data_14_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_365 <- list()
sim_list_14_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_365 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_365 <- out_100_14_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_365[[i]] <- sim_data_14_meta_365
}

sim_output_14_meta_365 <- bind_rows(sim_list_14_meta_365)
# Summary table of endpoint data
sim_output_14_meta_365 <- sim_output_14_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_365

# Make Summary Table of output
sim_summary_14_meta_365 <- sim_output_14_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_14_meta_365

Results

waning_results_14 <- sim_summary_14_meta %>%
  bind_rows(sim_summary_14_meta_10) %>%
  bind_rows(sim_summary_14_meta_20) %>%
  bind_rows(sim_summary_14_meta_30) %>%
  bind_rows(sim_summary_14_meta_40) %>%
  bind_rows(sim_summary_14_meta_50) %>%
  bind_rows(sim_summary_14_meta_60) %>%
  bind_rows(sim_summary_14_meta_70) %>%
  bind_rows(sim_summary_14_meta_80) %>%
  bind_rows(sim_summary_14_meta_90) %>%
  bind_rows(sim_summary_14_meta_180) %>%
  bind_rows(sim_summary_14_meta_110) %>%
  bind_rows(sim_summary_14_meta_120) %>%
  bind_rows(sim_summary_14_meta_130) %>%
  bind_rows(sim_summary_14_meta_150) %>%
  bind_rows(sim_summary_14_meta_220) %>%
  bind_rows(sim_summary_14_meta_270) %>%
  bind_rows(sim_summary_14_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 14)

write_csv(waning_results_14, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_14.csv")

waning_results_14
ggplot(waning_results_14, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

Combined Results

Results from sinale and metapopulation models were comined into one data frame and visualised.

combined_waning <- waning_results %>%
  bind_rows(waning_results_single) %>%
  bind_rows(waning_results_7) %>%
  bind_rows(waning_results_3) %>%
  bind_rows(waning_results_14)

head(combined_waning)


#write_csv(combined_waning, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/combined_waning_results.csv")
pal <- wes_palette(4, name = "Zissou1", type = "continuous")

combined_plot <- ggplot(combined_waning, aes(immunity_duration, sum_persist, colour = as.factor(patches)))+
  geom_line(alpha=0.7, size=1)+
  geom_point(alpha=0.5, size=2)+
  geom_segment(x = -Inf, y = 50, xend = 141.5, yend = 50, linetype = "dashed", colour = "grey") +
  geom_segment(x = 5, y = 50, xend = 5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 42.5, y = 50, xend = 42.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 91.5, y = 50, xend = 91.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 141.5, y = 50, xend = 141.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  scale_x_continuous(breaks = seq(0, 360, 50)) +
  labs(x = "Duration of immunity (days)",
       y = "Probability of persistence after 3 years (%)", 
       colour = "No. Patches")+
  scale_color_discrete(type = pal,
                       labels = c("1", "3", "7", "14"))+
  theme_bw()

combined_plot

ggsave(filename = "combined_plot_patches.pdf", plot = combined_plot, device = "pdf", width = 7, height = 5, path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Plots")
ggplot(combined_waning, aes(immunity_duration, mean_percent_infected, colour = as.factor(patches)))+
  geom_line()+
  geom_point() +
  labs(x = "Duration of immunity",
       y = "Proportion infected at endpoint (%)", 
       colour = "Patches")+
  scale_color_discrete(type = pal,
                       labels = c("1", "3", "7", "14"))+
  theme_bw()

3-Patch Single Population

<<<<<<< HEAD 3 more single population models were ran to understand if the increased probability of persistence was being caused by increasing population size. These models were the same as the initial single poulation model, but instead \(N\) was increased to the sum of 3, 7, or 14 randomly sampled campsizes from Dyble et al. (2021).

======= >>>>>>> 672728028f18b2fc224322993d245c9a6ee71bf1 ### Model Set-up

Model was set up with a single randomly selected camp size with a single infected individual and parameters for pathogen X.

# Define Paramenters
<<<<<<< HEAD
N_a <-    sum(sample(camps.data$camp_total, 3))    # Total Population size of three camps
=======
N_a <-    sum(sample(camps.data$camp_total, 3))    # Population size
>>>>>>> 672728028f18b2fc224322993d245c9a6ee71bf1
initial_infected <-  1    # Initial infected
simName <- "SEIRS model"       # Simulation name
tf <- 365*3

#Collect parameters
parms <- list(
  beta = 0.6,
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

#Create the named initial state vector for the U-patch system.

x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

names(x0_a) <- c("S","E","I", "R", "N")


# Define the state change matrix for a single patch
nu <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
a <-c(
        paste0("(beta*I/N)*S"), # Infection
        paste0("sigma*E"),                                       # Becomes infecious
        paste0("gamma*I"),                                       # Recovery from infection
        paste0("omega*R"),       # Loss of immunity
        paste0("mu*N"),                             # Births
        paste0("mu*S"),                                             # Deaths (S)
        paste0("mu*E"),                                             # Deaths (E)
        paste0("mu*I"),                                             # Deaths (I)
        paste0("mu*R"),                                             # Deaths (R)
        paste0("alpha*I")                                           # Deaths from infection
        
      )

Run Single Population Model


EIE_single <- EIE(R0_single, parms) # proportion of expected infecteds at equilibrium
EIE_single

expexted_infecteds <- EIE_single*N_a # number of expected infecteds at equilibrium
expexted_infecteds

sqrt(N_a) # magnitude of oscillations 
# Run simulations with the Direct method
set.seed(21)
out_a <- ssa(
  x0 = x0_a,
  a = a,
  nu = nu,
  parms = parms,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
) 



## Extra Plots
plot_data_a <- out_a$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

single_plot_a <- ggplot(data = plot_data_a, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  labs(x="Time (Days)",
       y="Number of Individuals", 
       colour="State")+
  geom_hline(yintercept = expexted_infecteds, linetype = 'dashed') +
  theme_bw()

single_plot_a
plot_data_a %>%
  filter(state == "I") %>%
  slice_max(count)

Outbreak peaked at day 32 with 31 infected individuals.

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_a <- list()
sim_list_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  set.seed(i)
  out_100_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_a <- out_100_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_a[[i]] <- sim_data_a
}

sim_output_a <- bind_rows(sim_list_a)
# Summary table of endpoint data
sim_output_a <- sim_output_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
head(sim_output_a)

# Make Summary Table of output
sim_summary_a <- sim_output_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100, 
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_a

Varying waining immunity

Waning immunity was thought to play an important role in the persistence of pathogen X so we incrementally increased the duration of immunity (by decreasing \(\omega\)) and calculated the probability of persistence after 3 years in 1000 stochastic simulations. Duration of immunity was increased from 1 day to a year.

0 Days

#Collect parameters
parms_0 <- parms
parms_0$omega <- 0

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_0_a <- list()
sim_list_0_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_0_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_0_a <- out_100_0_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_0_a[[i]] <- sim_data_0_a
}

sim_output_0_a <- bind_rows(sim_list_0_a)
# Summary table of endpoint data
sim_output_0_a <- sim_output_0_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_0_a

# Make Summary Table of output
sim_summary_0_a <- sim_output_0_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_0_a

1 Days

#Collect parameters
parms_1 <- parms
parms_1$omega <- 1

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_1_a <- list()
sim_list_1_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_1_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_1_a <- out_100_1_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_1_a[[i]] <- sim_data_1_a
}

sim_output_1_a <- bind_rows(sim_list_1_a)
# Summary table of endpoint data
sim_output_1_a <- sim_output_1_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_1_a

# Make Summary Table of output
sim_summary_1_a <- sim_output_1_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_1_a

3 Days

#Collect parameters
parms_3 <- parms
parms_3$omega <- 1/3

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_a <- list()
sim_list_3_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_3_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_a <- out_100_3_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_3_a[[i]] <- sim_data_3_a
}

sim_output_3_a <- bind_rows(sim_list_3_a)
# Summary table of endpoint data
sim_output_3_a <- sim_output_3_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_a

# Make Summary Table of output
sim_summary_3_a <- sim_output_3_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3_a

7 Days

#Collect parameters
parms_7 <- parms
parms_7$omega <- 1/7

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_7_a <- list()
sim_list_7_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))   # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_7_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_7_a <- out_100_7_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_7_a[[i]] <- sim_data_7_a
}

sim_output_7_a <- bind_rows(sim_list_7_a)
# Summary table of endpoint data
sim_output_7_a <- sim_output_7_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_7_a

# Make Summary Table of output
sim_summary_7_a <- sim_output_7_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_7_a

10 Days

#Collect parameters
parms_10 <- parms
parms_10$omega <- 1/10


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_10_a <- list()
sim_list_10_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_10_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_10_a <- out_100_10_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_10_a[[i]] <- sim_data_10_a
}

sim_output_10_a <- bind_rows(sim_list_10_a)
# Summary table of endpoint data
sim_output_10_a <- sim_output_10_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_10_a

# Make Summary Table of output
sim_summary_10_a <- sim_output_10_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_10_a

20 Days

#Collect parameters
parms_20 <- parms
parms_20$omega <- 1/20

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_20_a <- list()
sim_list_20_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_20_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_20_a <- out_100_20_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_20_a[[i]] <- sim_data_20_a
}

sim_output_20_a <- bind_rows(sim_list_20_a)
# Summary table of endpoint data
sim_output_20_a <- sim_output_20_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_20_a

# Make Summary Table of output
sim_summary_20_a <- sim_output_20_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_20_a

30 Days

#Collect parameters
parms_30 <- parms
parms_30$omega <- 1/30

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_30_a <- list()
sim_list_30_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_30_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_30_a <- out_100_30_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_30_a[[i]] <- sim_data_30_a
}

sim_output_30_a <- bind_rows(sim_list_30_a)
# Summary table of endpoint data
sim_output_30_a <- sim_output_30_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_30_a

# Make Summary Table of output
sim_summary_30_a <- sim_output_30_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_30_a

40 Days

#Collect parameters
parms_40 <- parms
parms_40$omega <- 1/40


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_40_a <- list()
sim_list_40_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_40_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_40_a <- out_100_40_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_40_a[[i]] <- sim_data_40_a
}

sim_output_40_a <- bind_rows(sim_list_40_a)
# Summary table of endpoint data
sim_output_40_a <- sim_output_40_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_40_a

# Make Summary Table of output
sim_summary_40_a <- sim_output_40_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_40_a

50 Days

#Collect parameters
parms_50 <- parms
parms_50$omega <- 1/50


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_50_a <- list()
sim_list_50_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_50_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_50_a <- out_100_50_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_50_a[[i]] <- sim_data_50_a
}

sim_output_50_a <- bind_rows(sim_list_50_a)
# Summary table of endpoint data
sim_output_50_a <- sim_output_50_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_50_a

# Make Summary Table of output
sim_summary_50_a <- sim_output_50_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_50_a

60 Days

#Collect parameters
parms_60 <- parms
parms_60$omega <- 1/60


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_60_a <- list()
sim_list_60_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_60_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_60_a <- out_100_60_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_60_a[[i]] <- sim_data_60_a
}

sim_output_60_a <- bind_rows(sim_list_60_a)
# Summary table of endpoint data
sim_output_60_a <- sim_output_60_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_60_a

# Make Summary Table of output
sim_summary_60_a <- sim_output_60_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_60_a

70 Days

#Collect parameters
parms_70 <- parms
parms_70$omega <- 1/70


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_70_a <- list()
sim_list_70_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_70_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_70_a <- out_100_70_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_70_a[[i]] <- sim_data_70_a
}

sim_output_70_a <- bind_rows(sim_list_70_a)
# Summary table of endpoint data
sim_output_70_a <- sim_output_70_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_70_a

# Make Summary Table of output
sim_summary_70_a <- sim_output_70_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_70_a

80 Days

#Collect parameters
parms_80 <- parms
parms_80$omega <- 1/80


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_80_a <- list()
sim_list_80_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_80_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_80_a <- out_100_80_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_80_a[[i]] <- sim_data_80_a
}

sim_output_80_a <- bind_rows(sim_list_80_a)
# Summary table of endpoint data
sim_output_80_a <- sim_output_80_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_80_a

# Make Summary Table of output
sim_summary_80_a <- sim_output_80_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_80_a

150 Days

#Collect parameters
parms_150 <- parms
parms_150$omega <- 1/150


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_150_a <- list()
sim_list_150_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_150_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_150_a <- out_100_150_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_150_a[[i]] <- sim_data_150_a
}

sim_output_150_a <- bind_rows(sim_list_150_a)
# Summary table of endpoint data
sim_output_150_a <- sim_output_150_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_150_a

# Make Summary Table of output
sim_summary_150_a <- sim_output_150_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_150_a

180 Days

#Collect parameters
parms_180 <- parms
parms_180$omega <- 1/180


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_180_a <- list()
sim_list_180_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_180_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_180_a <- out_100_180_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_180_a[[i]] <- sim_data_180_a
}

sim_output_180_a <- bind_rows(sim_list_180_a)
# Summary table of endpoint data
sim_output_180_a <- sim_output_180_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_180_a

# Make Summary Table of output
sim_summary_180_a <- sim_output_180_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_180_a

365 Days

#Collect parameters
parms_365 <- parms
parms_365$omega <- 1/365


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_365_a <- list()
sim_list_365_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_365_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_365_a <- out_100_365_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_365_a[[i]] <- sim_data_365_a
}

sim_output_365_a <- bind_rows(sim_list_365_a)
# Summary table of endpoint data
sim_output_365_a <- sim_output_365_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_365_a

# Make Summary Table of output
sim_summary_365_a <- sim_output_365_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_365_a

Results

waning_results_single_a <- sim_summary_a %>%
  bind_rows(sim_summary_1_a) %>%
  bind_rows(sim_summary_3_a) %>%
  bind_rows(sim_summary_7_a) %>%
  bind_rows(sim_summary_10_a) %>%
  bind_rows(sim_summary_20_a) %>%
  bind_rows(sim_summary_30_a) %>%
  bind_rows(sim_summary_40_a) %>%
  bind_rows(sim_summary_50_a) %>%
  bind_rows(sim_summary_60_a) %>%
  bind_rows(sim_summary_70_a) %>%
  bind_rows(sim_summary_80_a) %>%
  bind_rows(sim_summary_150_a) %>%
  bind_rows(sim_summary_180_a) %>%
  bind_rows(sim_summary_365_a) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model="single",
         patches = 3)

write_csv(waning_results_single_a, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_single_a.csv")

waning_results_single_a
ggplot(waning_results_single_a, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

7-Patch Single Population

<<<<<<< HEAD The same single population model was run with \(N\) defined as the sum of 7 randomly selected camp sizes.

======= >>>>>>> 672728028f18b2fc224322993d245c9a6ee71bf1 ### Model Set-up

Model was set up with a single randomly selected camp size with a single infected individual and parameters for pathogen X.

# Define Paramenters
<<<<<<< HEAD
N_b <-    sum(sample(camps.data$camp_total, 7))    # Total Population size of three camps
=======
N_b <-    sum(sample(camps.data$camp_total, 7))    # Population size
>>>>>>> 672728028f18b2fc224322993d245c9a6ee71bf1
initial_infected <-  1    # Initial infected
simName <- "SEIRS model"       # Simulation name
tf <- 365*3

#Collect parameters
parms <- list(
  beta = 0.6,
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

#Create the named initial state vector for the U-patch system.

x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

names(x0_b) <- c("S","E","I", "R", "N")


# Define the state change matrix for a single patch
nu <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
a <-c(
        paste0("(beta*I/N)*S"), # Infection
        paste0("sigma*E"),                                       # Becomes infecious
        paste0("gamma*I"),                                       # Recovery from infection
        paste0("omega*R"),       # Loss of immunity
        paste0("mu*N"),                             # Births
        paste0("mu*S"),                                             # Deaths (S)
        paste0("mu*E"),                                             # Deaths (E)
        paste0("mu*I"),                                             # Deaths (I)
        paste0("mu*R"),                                             # Deaths (R)
        paste0("alpha*I")                                           # Deaths from infection
        
      )

Run Single Population Model


EIE_single <- EIE(R0_single, parms) # proportion of expected infecteds at equilibrium
EIE_single

expexted_infecteds <- EIE_single*N_b # number of expected infecteds at equilibrium
expexted_infecteds

sqrt(N_b) # magnitude of oscillations 
# Run simulations with the Direct method
set.seed(21)
out_b <- ssa(
  x0 = x0_b,
  a = a,
  nu = nu,
  parms = parms,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
) 



## Extra Plots
plot_data_b <- out_b$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

single_plot_b <- ggplot(data = plot_data_b, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  labs(x="Time (Days)",
       y="Number of Individuals", 
       colour="State")+
  geom_hline(yintercept = expexted_infecteds, linetype = 'dashed') +
  theme_bw()

single_plot_b
plot_data_b %>%
  filter(state == "I") %>%
  slice_max(count)

Outbreak peaked at day 32 with 31 infected individuals.

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_b <- list()
sim_list_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  set.seed(i)
  out_100_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_b <- out_100_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_b[[i]] <- sim_data_b
}

sim_output_b <- bind_rows(sim_list_b)
# Summary table of endpoint data
sim_output_b <- sim_output_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
head(sim_output_b)

# Make Summary Table of output
sim_summary_b <- sim_output_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100, 
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_b

Varying waining immunity

Waning immunity was thought to play an important role in the persistence of pathogen X so we incrementally increased the duration of immunity (by decreasing \(\omega\)) and calculated the probability of persistence after 3 years in 1000 stochastic simulations. Duration of immunity was increased from 1 day to a year.

0 Days

#Collect parameters
parms_0 <- parms
parms_0$omega <- 0

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_0_b <- list()
sim_list_0_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_0_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_0_b <- out_100_0_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_0_b[[i]] <- sim_data_0_b
}

sim_output_0_b <- bind_rows(sim_list_0_b)
# Summary table of endpoint data
sim_output_0_b <- sim_output_0_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_0_b

# Make Summary Table of output
sim_summary_0_b <- sim_output_0_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_0_b

1 Days

#Collect parameters
parms_1 <- parms
parms_1$omega <- 1

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_1_b <- list()
sim_list_1_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_1_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_1_b <- out_100_1_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_1_b[[i]] <- sim_data_1_b
}

sim_output_1_b <- bind_rows(sim_list_1_b)
# Summary table of endpoint data
sim_output_1_b <- sim_output_1_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_1_b

# Make Summary Table of output
sim_summary_1_b <- sim_output_1_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_1_b

3 Days

#Collect parameters
parms_3 <- parms
parms_3$omega <- 1/3

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_b <- list()
sim_list_3_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_3_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_b <- out_100_3_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_3_b[[i]] <- sim_data_3_b
}

sim_output_3_b <- bind_rows(sim_list_3_b)
# Summary table of endpoint data
sim_output_3_b <- sim_output_3_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_b

# Make Summary Table of output
sim_summary_3_b <- sim_output_3_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3_b

7 Days

#Collect parameters
parms_7 <- parms
parms_7$omega <- 1/7

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_7_b <- list()
sim_list_7_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))   # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_7_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_7_b <- out_100_7_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_7_b[[i]] <- sim_data_7_b
}

sim_output_7_b <- bind_rows(sim_list_7_b)
# Summary table of endpoint data
sim_output_7_b <- sim_output_7_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_7_b

# Make Summary Table of output
sim_summary_7_b <- sim_output_7_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_7_b

10 Days

#Collect parameters
parms_10 <- parms
parms_10$omega <- 1/10


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_10_b <- list()
sim_list_10_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_10_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_10_b <- out_100_10_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_10_b[[i]] <- sim_data_10_b
}

sim_output_10_b <- bind_rows(sim_list_10_b)
# Summary table of endpoint data
sim_output_10_b <- sim_output_10_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_10_b

# Make Summary Table of output
sim_summary_10_b <- sim_output_10_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_10_b

20 Days

#Collect parameters
parms_20 <- parms
parms_20$omega <- 1/20

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_20_b <- list()
sim_list_20_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_20_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_20_b <- out_100_20_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_20_b[[i]] <- sim_data_20_b
}

sim_output_20_b <- bind_rows(sim_list_20_b)
# Summary table of endpoint data
sim_output_20_b <- sim_output_20_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_20_b

# Make Summary Table of output
sim_summary_20_b <- sim_output_20_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_20_b

30 Days

#Collect parameters
parms_30 <- parms
parms_30$omega <- 1/30

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_30_b <- list()
sim_list_30_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_30_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_30_b <- out_100_30_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_30_b[[i]] <- sim_data_30_b
}

sim_output_30_b <- bind_rows(sim_list_30_b)
# Summary table of endpoint data
sim_output_30_b <- sim_output_30_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_30_b

# Make Summary Table of output
sim_summary_30_b <- sim_output_30_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_30_b

40 Days

#Collect parameters
parms_40 <- parms
parms_40$omega <- 1/40


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_40_b <- list()
sim_list_40_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_40_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_40_b <- out_100_40_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_40_b[[i]] <- sim_data_40_b
}

sim_output_40_b <- bind_rows(sim_list_40_b)
# Summary table of endpoint data
sim_output_40_b <- sim_output_40_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_40_b

# Make Summary Table of output
sim_summary_40_b <- sim_output_40_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_40_b

50 Days

#Collect parameters
parms_50 <- parms
parms_50$omega <- 1/50


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_50_b <- list()
sim_list_50_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_50_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_50_b <- out_100_50_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_50_b[[i]] <- sim_data_50_b
}

sim_output_50_b <- bind_rows(sim_list_50_b)
# Summary table of endpoint data
sim_output_50_b <- sim_output_50_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_50_b

# Make Summary Table of output
sim_summary_50_b <- sim_output_50_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_50_b

60 Days

#Collect parameters
parms_60 <- parms
parms_60$omega <- 1/60


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_60_b <- list()
sim_list_60_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_60_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_60_b <- out_100_60_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_60_b[[i]] <- sim_data_60_b
}

sim_output_60_b <- bind_rows(sim_list_60_b)
# Summary table of endpoint data
sim_output_60_b <- sim_output_60_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_60_b

# Make Summary Table of output
sim_summary_60_b <- sim_output_60_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_60_b

70 Days

#Collect parameters
parms_70 <- parms
parms_70$omega <- 1/70


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_70_b <- list()
sim_list_70_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_70_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_70_b <- out_100_70_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_70_b[[i]] <- sim_data_70_b
}

sim_output_70_b <- bind_rows(sim_list_70_b)
# Summary table of endpoint data
sim_output_70_b <- sim_output_70_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_70_b

# Make Summary Table of output
sim_summary_70_b <- sim_output_70_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_70_b

80 Days

#Collect parameters
parms_80 <- parms
parms_80$omega <- 1/80


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_80_b <- list()
sim_list_80_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_80_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_80_b <- out_100_80_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_80_b[[i]] <- sim_data_80_b
}

sim_output_80_b <- bind_rows(sim_list_80_b)
# Summary table of endpoint data
sim_output_80_b <- sim_output_80_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_80_b

# Make Summary Table of output
sim_summary_80_b <- sim_output_80_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_80_b

90 Days

#Collect parameters
parms_90 <- parms
parms_90$omega <- 1/90


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_90_b <- list()
sim_list_90_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_90_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_90_b <- out_100_90_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_90_b[[i]] <- sim_data_90_b
}

sim_output_90_b <- bind_rows(sim_list_90_b)
# Summary table of endpoint data
sim_output_90_b <- sim_output_90_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_90_b

# Make Summary Table of output
sim_summary_90_b <- sim_output_90_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_90_b

110 Days

#Collect parameters
parms_110 <- parms
parms_110$omega <- 1/110


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_110_b <- list()
sim_list_110_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_110_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_110_b <- out_100_110_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_110_b[[i]] <- sim_data_110_b
}

sim_output_110_b <- bind_rows(sim_list_110_b)
# Summary table of endpoint data
sim_output_110_b <- sim_output_110_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_110_b

# Make Summary Table of output
sim_summary_110_b <- sim_output_110_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_110_b

120 Days

#Collect parameters
parms_120 <- parms
parms_120$omega <- 1/120


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_120_b <- list()
sim_list_120_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_120_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_120_b <- out_100_120_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_120_b[[i]] <- sim_data_120_b
}

sim_output_120_b <- bind_rows(sim_list_120_b)
# Summary table of endpoint data
sim_output_120_b <- sim_output_120_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_120_b

# Make Summary Table of output
sim_summary_120_b <- sim_output_120_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_120_b

130 Days

#Collect parameters
parms_130 <- parms
parms_130$omega <- 1/130


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_130_b <- list()
sim_list_130_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_130_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_130_b <- out_100_130_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_130_b[[i]] <- sim_data_130_b
}

sim_output_130_b <- bind_rows(sim_list_130_b)
# Summary table of endpoint data
sim_output_130_b <- sim_output_130_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_130_b

# Make Summary Table of output
sim_summary_130_b <- sim_output_130_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_130_b

150 Days

#Collect parameters
parms_150 <- parms
parms_150$omega <- 1/150


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_150_b <- list()
sim_list_150_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_150_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_150_b <- out_100_150_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_150_b[[i]] <- sim_data_150_b
}

sim_output_150_b <- bind_rows(sim_list_150_b)
# Summary table of endpoint data
sim_output_150_b <- sim_output_150_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_150_b

# Make Summary Table of output
sim_summary_150_b <- sim_output_150_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_150_b

180 Days

#Collect parameters
parms_180 <- parms
parms_180$omega <- 1/180


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_180_b <- list()
sim_list_180_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_180_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_180_b <- out_100_180_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_180_b[[i]] <- sim_data_180_b
}

sim_output_180_b <- bind_rows(sim_list_180_b)
# Summary table of endpoint data
sim_output_180_b <- sim_output_180_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_180_b

# Make Summary Table of output
sim_summary_180_b <- sim_output_180_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_180_b

365 Days

#Collect parameters
parms_365 <- parms
parms_365$omega <- 1/365


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_365_b <- list()
sim_list_365_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_365_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_365_b <- out_100_365_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_365_b[[i]] <- sim_data_365_b
}

sim_output_365_b <- bind_rows(sim_list_365_b)
# Summary table of endpoint data
sim_output_365_b <- sim_output_365_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_365_b

# Make Summary Table of output
sim_summary_365_b <- sim_output_365_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_365_b

Results

waning_results_single_b <- sim_summary_b %>%
  bind_rows(sim_summary_1_b) %>%
  bind_rows(sim_summary_3_b) %>%
  bind_rows(sim_summary_7_b) %>%
  bind_rows(sim_summary_10_b) %>%
  bind_rows(sim_summary_20_b) %>%
  bind_rows(sim_summary_30_b) %>%
  bind_rows(sim_summary_40_b) %>%
  bind_rows(sim_summary_50_b) %>%
  bind_rows(sim_summary_60_b) %>%
  bind_rows(sim_summary_70_b) %>%
  bind_rows(sim_summary_80_b) %>%
  bind_rows(sim_summary_90_b) %>%
  bind_rows(sim_summary_110_b) %>%
  bind_rows(sim_summary_120_b) %>%
  bind_rows(sim_summary_130_b) %>%
  bind_rows(sim_summary_150_b) %>%
  bind_rows(sim_summary_180_b) %>%
  bind_rows(sim_summary_365_b) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model="single",
         patches = 7)

write_csv(waning_results_single_b, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_single_b.csv")

waning_results_single_b
ggplot(waning_results_single_b, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

14-Patch Single Population

<<<<<<< HEAD The same single population model was ran with \(N\) defined as the sum of 14 randomly sampled camp sizes.

======= >>>>>>> 672728028f18b2fc224322993d245c9a6ee71bf1 ### Model Set-up

Model was set up with a single randomly selected camp size with a single infected individual and parameters for pathogen X.

# Define Paramenters
<<<<<<< HEAD
N_c <-    sum(sample(camps.data$camp_total, 14))    # Total Population size of three camps
=======
N_c <-    sum(sample(camps.data$camp_total, 14))    # Population size
>>>>>>> 672728028f18b2fc224322993d245c9a6ee71bf1
initial_infected <-  1    # Initial infected
simName <- "SEIRS model"       # Simulation name
tf <- 365*3

#Collect parameters
parms <- list(
  beta = 0.6,
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

#Create the named initial state vector for the U-patch system.

x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

names(x0_c) <- c("S","E","I", "R", "N")


# Define the state change matrix for a single patch
nu <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
a <-c(
        paste0("(beta*I/N)*S"), # Infection
        paste0("sigma*E"),                                       # Becomes infecious
        paste0("gamma*I"),                                       # Recovery from infection
        paste0("omega*R"),       # Loss of immunity
        paste0("mu*N"),                             # Births
        paste0("mu*S"),                                             # Deaths (S)
        paste0("mu*E"),                                             # Deaths (E)
        paste0("mu*I"),                                             # Deaths (I)
        paste0("mu*R"),                                             # Deaths (R)
        paste0("alpha*I")                                           # Deaths from infection
        
      )

Run Single Population Model


EIE_single <- EIE(R0_single, parms) # proportion of expected infecteds at equilibrium
EIE_single

expexted_infecteds <- EIE_single*N_c # number of expected infecteds at equilibrium
expexted_infecteds

sqrt(N_c) # magnitude of oscillations 
# Run simulations with the Direct method
<<<<<<< HEAD
set.seed(25)
=======
set.seed(21)
>>>>>>> 672728028f18b2fc224322993d245c9a6ee71bf1
out_c <- ssa(
  x0 = x0_c,
  a = a,
  nu = nu,
  parms = parms,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
) 



## Extra Plots
plot_data_c <- out_c$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

single_plot_c <- ggplot(data = plot_data_c, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  labs(x="Time (Days)",
       y="Number of Individuals", 
       colour="State")+
  geom_hline(yintercept = expexted_infecteds, linetype = 'dashed') +
  theme_bw()

single_plot_c
plot_data_c %>%
  filter(state == "I") %>%
  slice_max(count)

Outbreak peaked at day 32 with 31 infected individuals.

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_c <- list()
sim_list_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  set.seed(i)
  out_100_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_c <- out_100_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_c[[i]] <- sim_data_c
}

sim_output_c <- bind_rows(sim_list_c)
# Summary table of endpoint data
sim_output_c <- sim_output_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
head(sim_output_c)

# Make Summary Table of output
sim_summary_c <- sim_output_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100, 
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_c

Varying waining immunity

Waning immunity was thought to play an important role in the persistence of pathogen X so we incrementally increased the duration of immunity (by decreasing \(\omega\)) and calculated the probability of persistence after 3 years in 1000 stochastic simulations. Duration of immunity was increased from 1 day to a year.

0 Days

#Collect parameters
parms_0 <- parms
parms_0$omega <- 0

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_0_c <- list()
sim_list_0_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_0_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_0_c <- out_100_0_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_0_c[[i]] <- sim_data_0_c
}

sim_output_0_c <- bind_rows(sim_list_0_c)
# Summary table of endpoint data
sim_output_0_c <- sim_output_0_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_0_c

# Make Summary Table of output
sim_summary_0_c <- sim_output_0_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_0_c

1 Days

#Collect parameters
parms_1 <- parms
parms_1$omega <- 1

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_1_c <- list()
sim_list_1_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_1_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_1_c <- out_100_1_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_1_c[[i]] <- sim_data_1_c
}

sim_output_1_c <- bind_rows(sim_list_1_c)
# Summary table of endpoint data
sim_output_1_c <- sim_output_1_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_1_c

# Make Summary Table of output
sim_summary_1_c <- sim_output_1_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_1_c

3 Days

#Collect parameters
parms_3 <- parms
parms_3$omega <- 1/3

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_c <- list()
sim_list_3_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_3_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_c <- out_100_3_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_3_c[[i]] <- sim_data_3_c
}

sim_output_3_c <- bind_rows(sim_list_3_c)
# Summary table of endpoint data
sim_output_3_c <- sim_output_3_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_c

# Make Summary Table of output
sim_summary_3_c <- sim_output_3_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3_c

7 Days

#Collect parameters
parms_7 <- parms
parms_7$omega <- 1/7

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_7_c <- list()
sim_list_7_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))   # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_7_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_7_c <- out_100_7_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_7_c[[i]] <- sim_data_7_c
}

sim_output_7_c <- bind_rows(sim_list_7_c)
# Summary table of endpoint data
sim_output_7_c <- sim_output_7_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_7_c

# Make Summary Table of output
sim_summary_7_c <- sim_output_7_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_7_c

10 Days

#Collect parameters
parms_10 <- parms
parms_10$omega <- 1/10


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_10_c <- list()
sim_list_10_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_10_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_10_c <- out_100_10_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_10_c[[i]] <- sim_data_10_c
}

sim_output_10_c <- bind_rows(sim_list_10_c)
# Summary table of endpoint data
sim_output_10_c <- sim_output_10_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_10_c

# Make Summary Table of output
sim_summary_10_c <- sim_output_10_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_10_c

20 Days

#Collect parameters
parms_20 <- parms
parms_20$omega <- 1/20

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_20_c <- list()
sim_list_20_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_20_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_20_c <- out_100_20_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_20_c[[i]] <- sim_data_20_c
}

sim_output_20_c <- bind_rows(sim_list_20_c)
# Summary table of endpoint data
sim_output_20_c <- sim_output_20_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_20_c

# Make Summary Table of output
sim_summary_20_c <- sim_output_20_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_20_c

30 Days

#Collect parameters
parms_30 <- parms
parms_30$omega <- 1/30

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_30_c <- list()
sim_list_30_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_30_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_30_c <- out_100_30_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_30_c[[i]] <- sim_data_30_c
}

sim_output_30_c <- bind_rows(sim_list_30_c)
# Summary table of endpoint data
sim_output_30_c <- sim_output_30_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_30_c

# Make Summary Table of output
sim_summary_30_c <- sim_output_30_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_30_c

40 Days

#Collect parameters
parms_40 <- parms
parms_40$omega <- 1/40


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_40_c <- list()
sim_list_40_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_40_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_40_c <- out_100_40_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_40_c[[i]] <- sim_data_40_c
}

sim_output_40_c <- bind_rows(sim_list_40_c)
# Summary table of endpoint data
sim_output_40_c <- sim_output_40_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_40_c

# Make Summary Table of output
sim_summary_40_c <- sim_output_40_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_40_c

50 Days

#Collect parameters
parms_50 <- parms
parms_50$omega <- 1/50


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_50_c <- list()
sim_list_50_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_50_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_50_c <- out_100_50_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_50_c[[i]] <- sim_data_50_c
}

sim_output_50_c <- bind_rows(sim_list_50_c)
# Summary table of endpoint data
sim_output_50_c <- sim_output_50_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_50_c

# Make Summary Table of output
sim_summary_50_c <- sim_output_50_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_50_c

60 Days

#Collect parameters
parms_60 <- parms
parms_60$omega <- 1/60


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_60_c <- list()
sim_list_60_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_60_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_60_c <- out_100_60_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_60_c[[i]] <- sim_data_60_c
}

sim_output_60_c <- bind_rows(sim_list_60_c)
# Summary table of endpoint data
sim_output_60_c <- sim_output_60_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_60_c

# Make Summary Table of output
sim_summary_60_c <- sim_output_60_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_60_c

70 Days

#Collect parameters
parms_70 <- parms
parms_70$omega <- 1/70


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_70_c <- list()
sim_list_70_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_70_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_70_c <- out_100_70_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_70_c[[i]] <- sim_data_70_c
}

sim_output_70_c <- bind_rows(sim_list_70_c)
# Summary table of endpoint data
sim_output_70_c <- sim_output_70_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_70_c

# Make Summary Table of output
sim_summary_70_c <- sim_output_70_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_70_c

80 Days

#Collect parameters
parms_80 <- parms
parms_80$omega <- 1/80


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_80_c <- list()
sim_list_80_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_80_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_80_c <- out_100_80_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_80_c[[i]] <- sim_data_80_c
}

sim_output_80_c <- bind_rows(sim_list_80_c)
# Summary table of endpoint data
sim_output_80_c <- sim_output_80_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_80_c

# Make Summary Table of output
sim_summary_80_c <- sim_output_80_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_80_c

90 Days

#Collect parameters
parms_90 <- parms
parms_90$omega <- 1/90


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_90_c <- list()
sim_list_90_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_90_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_90_c <- out_100_90_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_90_c[[i]] <- sim_data_90_c
}

sim_output_90_c <- bind_rows(sim_list_90_c)
# Summary table of endpoint data
sim_output_90_c <- sim_output_90_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_90_c

# Make Summary Table of output
sim_summary_90_c <- sim_output_90_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_90_c

110 Days

#Collect parameters
parms_110 <- parms
parms_110$omega <- 1/110


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_110_c <- list()
sim_list_110_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_110_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_110_c <- out_100_110_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_110_c[[i]] <- sim_data_110_c
}

sim_output_110_c <- bind_rows(sim_list_110_c)
# Summary table of endpoint data
sim_output_110_c <- sim_output_110_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_110_c

# Make Summary Table of output
sim_summary_110_c <- sim_output_110_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_110_c

120 Days

#Collect parameters
parms_120 <- parms
parms_120$omega <- 1/120


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_120_c <- list()
sim_list_120_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_120_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_120_c <- out_100_120_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_120_c[[i]] <- sim_data_120_c
}

sim_output_120_c <- bind_rows(sim_list_120_c)
# Summary table of endpoint data
sim_output_120_c <- sim_output_120_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_120_c

# Make Summary Table of output
sim_summary_120_c <- sim_output_120_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_120_c

130 Days

#Collect parameters
parms_130 <- parms
parms_130$omega <- 1/130


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_130_c <- list()
sim_list_130_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_130_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_130_c <- out_100_130_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_130_c[[i]] <- sim_data_130_c
}

sim_output_130_c <- bind_rows(sim_list_130_c)
# Summary table of endpoint data
sim_output_130_c <- sim_output_130_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_130_c

# Make Summary Table of output
sim_summary_130_c <- sim_output_130_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_130_c

150 Days

#Collect parameters
parms_150 <- parms
parms_150$omega <- 1/150


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_150_c <- list()
sim_list_150_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_150_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_150_c <- out_100_150_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_150_c[[i]] <- sim_data_150_c
}

sim_output_150_c <- bind_rows(sim_list_150_c)
# Summary table of endpoint data
sim_output_150_c <- sim_output_150_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_150_c

# Make Summary Table of output
sim_summary_150_c <- sim_output_150_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_150_c

180 Days

#Collect parameters
parms_180 <- parms
parms_180$omega <- 1/180


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_180_c <- list()
sim_list_180_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_180_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_180_c <- out_100_180_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_180_c[[i]] <- sim_data_180_c
}

sim_output_180_c <- bind_rows(sim_list_180_c)
# Summary table of endpoint data
sim_output_180_c <- sim_output_180_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_180_c

# Make Summary Table of output
sim_summary_180_c <- sim_output_180_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_180_c

220 Days

#Collect parameters
parms_220 <- parms
parms_220$omega <- 1/220


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_220_c <- list()
sim_list_220_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_220_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_220_c <- out_100_220_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_220_c[[i]] <- sim_data_220_c
}

sim_output_220_c <- bind_rows(sim_list_220_c)
# Summary table of endpoint data
sim_output_220_c <- sim_output_220_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_220_c

# Make Summary Table of output
sim_summary_220_c <- sim_output_220_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_220_c

270 Days

#Collect parameters
parms_270 <- parms
parms_270$omega <- 1/270


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_270_c <- list()
sim_list_270_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_270_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_270_c <- out_100_270_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_270_c[[i]] <- sim_data_270_c
}

sim_output_270_c <- bind_rows(sim_list_270_c)
# Summary table of endpoint data
sim_output_270_c <- sim_output_270_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_270_c

# Make Summary Table of output
sim_summary_270_c <- sim_output_270_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_270_c

365 Days

#Collect parameters
parms_365 <- parms
parms_365$omega <- 1/365


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_365_c <- list()
sim_list_365_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_365_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_365_c <- out_100_365_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_365_c[[i]] <- sim_data_365_c
}

sim_output_365_c <- bind_rows(sim_list_365_c)
ggsave(filename = "combined_plot_patches_2.pdf", plot = combined_plot_2, device = "pdf", width = 7, height = 5, path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Plots")

Results

waning_results_single_c <- sim_summary_c %>%
  bind_rows(sim_summary_1_c) %>%
  bind_rows(sim_summary_3_c) %>%
  bind_rows(sim_summary_7_c) %>%
  bind_rows(sim_summary_10_c) %>%
  bind_rows(sim_summary_20_c) %>%
  bind_rows(sim_summary_30_c) %>%
  bind_rows(sim_summary_40_c) %>%
  bind_rows(sim_summary_50_c) %>%
  bind_rows(sim_summary_60_c) %>%
  bind_rows(sim_summary_70_c) %>%
  bind_rows(sim_summary_80_c) %>%
  bind_rows(sim_summary_90_c) %>%
  bind_rows(sim_summary_110_c) %>%
  bind_rows(sim_summary_120_c) %>%
  bind_rows(sim_summary_130_c) %>%
  bind_rows(sim_summary_150_c) %>%
  bind_rows(sim_summary_180_c) %>%
  bind_rows(sim_summary_220_c) %>%
  bind_rows(sim_summary_270_c) %>%
  bind_rows(sim_summary_365_c) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model="single",
         patches = 14)

write_csv(waning_results_single_c, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_single_c.csv")

waning_results_single_c
ggplot(waning_results_single_c, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

Combined Meta and Single Results

combined_waning_2 <- read_csv("Results/combined_waning_results.csv")%>%
  bind_rows(waning_results_single_a) %>%
  bind_rows(waning_results_single_b) %>%
  bind_rows(waning_results_single_c)

combined_waning_2

write_csv(combined_waning_2, "Results/combined_waning_results_2.csv")

combined_plot_2 <- ggplot(combined_waning_2, aes(immunity_duration, sum_persist, colour = as.factor(patches), linetype = model))+
  geom_line(alpha=0.9, size=1)+
  #geom_point(alpha=0.5, size=1.5)+
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  scale_x_continuous(breaks = seq(0, 360, 50)) +
  labs(x = "Duration of immunity (days)",
       y = "Probability of persistence after 3 years (%)", 
       colour = "No. Camps",
       linetype = "Model Type")+
  scale_color_discrete(type = pal,
                         #wes_palettes$AsteroidCity3,
                       labels = c("1", "3", "7", "14"))+
  scale_linetype_discrete(labels = c("Metapopulation", "Single Population")) +
  theme_bw()

combined_plot_2
ggsave(filename = "combined_plot_patches_2.pdf", plot = combined_plot_2, device = "pdf", width = 7, height = 5, path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Plots")
pathogenX_results <- combined_waning_2 %>%
  filter(omega == 0.01)

pathogenX_results
pathogenX_bar <- ggplot(pathogenX_results, aes(as.factor(patches), sum_persist, groupName = model, fill = model)) +
  geom_col(position=position_dodge(), colour = "black") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(x = "No. Camps",
       y = "Probability of persistence after 3 years (%)",
       fill = "Model Type") +
  scale_fill_discrete(
    type = wes_palettes$AsteroidCity3,
    labels = c("Metapopulation", "Single Population")) +
  theme_bw()

pathogenX_bar
ggsave(filename = "pathogenX_bar.pdf", plot = pathogenX_bar, device = "pdf", width = 7, height = 4, path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Plots")

Combined plots

library(ggpubr)
library(grid)
theme_set(theme_pubr())

double_combined_plot <- ggarrange(combined_plot + rremove("xlab") + rremove("ylab"), combined_plot_2 + rremove("xlab") + rremove("ylab"),
          labels = c("A", "B"),
          font.label = list(size = 12, face = "plain"),
          vjust = 1,
          ncol = 2, nrow = 1,
          legend.grob = get_legend(combined_plot_2),
          legend = "right"
          )

double_combined_plot <- annotate_figure(double_combined_plot, left = textGrob("Probability of persistence after 3 years (%)", rot = 90, vjust = 1, gp = gpar(cex = 1)),
                    bottom = textGrob("Duration of immunity (days)", hjust = 0.8, gp = gpar(cex = 1)))

double_combined_plot
ggsave(filename = "double_immunity_plot.pdf", plot = double_combined_plot, device = "pdf", width = 8, height = 4, path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Plots")

References

LS0tCnRpdGxlOiAiTW9kZWxsaW5nIHRoZSBwZXJzaXN0ZW5jZSBvZiBpbmZlY3Rpb3VzIGRpc2Vhc2VzIGluIHByZS1hZ3JpY3VsdHVyYWwgSHVudGVyLWdhdGhlcmVycyIKc3VidGl0bGU6ICJGaW5hbCBBbmFseXNpcyBSZXBvcnQiCmF1dGhvcjogIk1hdHRoZXcgSG95bGUiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICAgIHRoZW1lOiB5ZXRpCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzCi0tLQojIyBTZXQtdXAKYGBge3J9CiMgcm0obGlzdCA9IGxzKCkpCmxpYnJhcnkod2VzYW5kZXJzb24pCmxpYnJhcnkoR2lsbGVzcGllU1NBKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShHQSkKYGBgCgojIyBCYWNrZ3JvdW5kCgpUaGUgdHJhZGl0aW9uYWxseSBoZWxkIGJlbGllZiB0aGF0IG1vc3QgbW9kZXJuIGluZmVjdGlvdXMgZGlzZWFzZXMgZW1lcmdlZCB3aGVuIGh1bWFucyBiZWdhbiBsaXZpbmcgaW4gbGFyZ2VyIGFncmljdWx0dXJhbCBzZXR0bGVtZW50cyBoYXMgYmVlbiBjaGFsbGVuZ2VkIGJ5IHN0dWRpZXMgb2YgbW9kZXJuIGh1bnRlci1nYXRoZXJlcnMuIFRoaXMgc3R1ZHkgd2lsbCBpbnZlc3RpZ2F0ZSB3aGljaCBlbWVyZ2luZyBwYXRob2dlbnMgbWF5IHBlcnNpc3QgaW4gaHVudGVyLWdhdGhlcmVyIGdyb3VwcyBieSBjb25zdHJ1Y3RpbmcgYSBjb21wYXJ0bWVudCBtb2RlbCBvZiBpbmZlY3Rpb3VzIGRpc2Vhc2UgdHJhbnNtaXNzaW9uIHRoYXQgYWNjb3VudHMgZm9yIGRlbW9ncmFwaHkgYW5kIG11bHRpLWJhbmQgc3RydWN0dXJlLiBUaGlzIHN0dWR5IHdpbGwgbG9vayB0byB1bmRlcnN0YW5kIGhvdyB0aGUgY3JpdGljYWwgY29tbXVuaXR5IHNpemUgcmVxdWlyZWQgdG8gc3VzdGFpbiBhbiBvdXRicmVhayBpcyBhZmZlY3RlZCBieSBob3N0IHBvcHVsYXRpb24gZHluYW1pY3MuIFdlIHNob3cgdGhhdCBtZXRhcG9wdWxhdGlvbiBzdHJ1Y3R1cmUgaW5jcmVhc2VzIHRoZSBwcm9iYWJpbGl0eSBvZiBhIHJlc3BpcmF0b3J5IHBhdGhvZ2VuIHdpdGggd2FuaW5nIGltbXVuaXR5IHBlcnNpc3RpbmcgYWZ0ZXIgMyB5ZWFycy4gVGhlIHByb2JhYmlsaXR5IG9mIHBlcnNpc3RlbmNlIGluY3JlYXNlcyB3aXRoIHRoZSBudW1iZXIgb2Ygc3ViLXBvcHVsYXRpb25zIGJ1dCBpcyBsYXJnZWx5IGRldGVybWluZWQgYnkgdGhlIGR1cmF0aW9uIG9mIGltbXVuaXR5LiBVbmRlcnN0YW5kaW5nIHRoZSBvcmlnaW5zIG9mIGluZmVjdGlvdXMgZGlzZWFzZXMgaXMgYW4gaW1wb3J0YW50IGFyZWEgb2YgcmVzZWFyY2ggdGhhdCB3aWxsIGxlYWQgdG8gaW1wcm92ZWQgc3RyYXRlZ2llcyBmb3IgcmVkdWNpbmcgdGhlaXIgZ2xvYmFsIGJ1cmRlbi4KClRoaXMgcmVwb3J0IHdpbGwgY292ZXIgdGhlIGZ1bGwgYW5hbHlzaXMgdW5kZXJ0YWtlbiB0byBnZW5lcmF0ZSB0aGUgcmVzdWx0cyB1c2VkIGluIG15IE1TYyBwcm9qZWN0LiBBIGZ1bGwgZGVzY3JpcHRpb24gb2YgdGhlIHJlc2VhcmNoIHByb2plY3QgYWltcyBhbmQgbWV0aG9kcyBjYW4gYmUgZm91bmQgaW4gdGhlIGZpbmFsIHBhcGVyIGluIHRoZSBbYEh1bnRlcl9HYXRoZXJlcl9tb2RlbHNgXShodHRwczovL2dpdGh1Yi5jb20vbWF0dGhld2hveWxlL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMpIEdpdEh1YiByZXBvc2l0b3J5LiAgU29tZSBjb2RlIHVzZWQgaW4gdGhpcyBwcm9qZWN0IHdhcyBhZGFwdGVkIGZyb20gdGhlIHR1dG9yaWFscyBhdHRhY2hlZCB0byB0aGUgYEdpbGxlc3BpZVNTQWAgcGFja2FnZS4gCgojIyBNb2RlbCBQYXJhbWV0ZXIgZXN0aW1hdGlvbgoKIyMjIEFndGEgSHVudGVyLUdhdGhlcmVyIERlbW9ncmFwaHkKCk1vZGVybi1kYXkgaHVudGVyLWdhdGhlcmVycyBhcmUgb2Z0ZW4gdXNlZCB0byBtYWtlIGluZmVyZW5jZXMgYWJvdXQgcHJlLWFncmljdWx0dXJhbCBodW1hbiBwb3B1bGF0aW9ucy4gVGhpcyBzdHVkeSBtb2RlbGVkIHRoZSBob3N0IHBvcHVsYXRpb24gb24gYSBncm91cCBvZiBpbmRpZ2Vub3VzIGh1bnRlci1nYXRoZXJlcnMgZnJvbSB0aGUgTm9ydGhlcm4gUGhpbGxpcGluZXMga25vd24gYXMgdGhlIEFndGEuIEluZm9ybWF0aW9uIHJlZ2FyZGluZyBiaXJ0aHMsIGRlYXRocyBhbmQgcG9wdWxhdGlvbiBzaXplIHdlcmUgb2J0YWluIGZyb20gYSBzdHVkeSBjb25kdWN0ZWQgYnkgSGVhZGxhbmQgZXQgYWwuLCAoMjAxMSkuIEF1dGhvcnMgY29uZHVjdGVkIGEgY2Vuc3VzLWxpa2Ugc3VydmV5IG9mIHRoZSBBZ3RhIHRoYXQgZm9sbG93ZWQgJFxzaW0kNCwzMDAgaW5kaXZpZHVhbHMgb3ZlciB0aGUgcGVyaW9kIG9mIDE5NTAtMjAxMC4gVGhpcyBkYXRlIHdhcyBmaXJzdCBleHBsb3JlZCB0byB1bmRlcnN0YW5kIEFndGEgZGVtb2dyYXBoeS4KCgpgYGB7cn0KYWd0YV9kZW1vIDwtIHJlYWQuY3N2KCJBZ3RhX0RhdGEvQWd0YVBvcER5bmFtaWNzX0hlYWRsYW5kMjAwNy5jc3YiKQoKZ2dwbG90KGFndGFfZGVtbywgYWVzKHg9WWVhcikpICsKICBnZW9tX2xpbmUoYWVzKHk9UG9wU2l6ZSksIGNvbG91ciA9IHdlc19wYWxldHRlcyREYXJqZWVsaW5nMVsxXSkgKwogIGdlb21fbGluZShhZXMoeT1CaXJ0aHMpLCBjb2xvdXIgPSB3ZXNfcGFsZXR0ZXMkRGFyamVlbGluZzFbMl0pICsKICBnZW9tX2xpbmUoYWVzKHk9RGVhdGhzKSwgY29sb3VyID0gd2VzX3BhbGV0dGVzJERhcmplZWxpbmcxWzNdKSArCiAgdGhlbWVfYncoKQpgYGAKCiMjIyMgUG9wdWxhdGlvbiBTaXplCmBgYHtyfQpoaXN0KGFndGFfZGVtbyRQb3BTaXplKQpzdW1tYXJ5KGFndGFfZGVtbyRQb3BTaXplKQpgYGAKCiMjIyMgQmlydGhzCmBgYHtyfQpoaXN0KGFndGFfZGVtbyRCaXJ0aHMpCnN1bW1hcnkoYWd0YV9kZW1vJEJpcnRocykKYGBgCgojIyMjIERlYXRocwpgYGB7cn0KaGlzdChhZ3RhX2RlbW8kRGVhdGhzKQpzdW1tYXJ5KGFndGFfZGVtbyREZWF0aHMpCmBgYAoKIyMjIyBCaXJ0aC9EZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQoKQmlydGggcmF0ZSB3YXMgZXN0aW1hdGVkIGZyb20gdGhpcyBkYXRhIGJ5IHRha2luZyB0aGUgbWVhbiBvZiB0aGUgYW5udWFsIG51bWJlciBvZiBiaXJ0aHMgZGl2aWRlZCBieSB0d28gdGltZXMgdGhlIGFubnVhbCBudW1iZXIgb2YgZmVtYWxlcy4gVGhpcyB3YXMgdGhlbiBzY2FsZWQgYXBwcm9wcmlhdGVseSB0byBvYnRhaW4gdGhlIGRhaWx5IG1lYW4gYmlydGggcmF0ZSBwZXIgcGVyc29uLiAKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmFndGFfZGVtbyA8LSBhZ3RhX2RlbW8gJT4lCiAgbXV0YXRlKEJpcnRoX3JhdGUgPSBCaXJ0aHMvKEZlbWFsZSoyKSwKICAgICAgICAgQmlydGhfcmF0ZV9kYWlseSA9ICgxICsgQmlydGhfcmF0ZSkgXiAoMS8zNjUpIC0gMSwKICAgICAgICAgRGVhdGhfcmF0ZSA9IChEZWF0aHMvUG9wU2l6ZSksCiAgICAgICAgIERlYXRoX3JhdGVfZGFpbHkgPSAoMSArIERlYXRoX3JhdGUpIF4gKDEvMzY1KSAtIDEsCiAgICAgICAgIFBvcENoYW5nZSA9IChkaWZmID0gUG9wU2l6ZSAtIGxhZyhQb3BTaXplLCBkZWZhdWx0ID0gZmlyc3QoUG9wU2l6ZSkpKSwKICAgICAgICAgUG9wQ2hhbmdlX3JhdGUgPSBhYnMoUG9wQ2hhbmdlKS9Qb3BTaXplLAogICAgICAgICBQb3BDaGFuZ2VfcmF0ZV9kYWlseSA9ICgxICsgUG9wQ2hhbmdlX3JhdGUpIF4gKDEvMzY1KSAtIDEpCmhlYWQoYWd0YV9kZW1vKQoKCmhpc3QoYWd0YV9kZW1vJEJpcnRoX3JhdGUpCmhpc3QoYWd0YV9kZW1vJERlYXRoX3JhdGUpCgpnZ3Bsb3QoYWd0YV9kZW1vLCBhZXMoeD1ZZWFyKSkgKwogIGdlb21fbGluZShhZXMoeT1CaXJ0aF9yYXRlKSwgY29sb3VyID0gd2VzX3BhbGV0dGVzJERhcmplZWxpbmcxWzJdKSArCiAgZ2VvbV9saW5lKGFlcyh5PURlYXRoX3JhdGUpLCBjb2xvdXIgPSB3ZXNfcGFsZXR0ZXMkRGFyamVlbGluZzFbM10pICsKICB0aGVtZV9idygpCgpkZW1vX3N1bSA8LSBhZ3RhX2RlbW8gJT4lCiAgc2VsZWN0KFBvcFNpemUsIEJpcnRoX3JhdGUsIEJpcnRoX3JhdGVfZGFpbHksIERlYXRoX3JhdGUsIERlYXRoX3JhdGVfZGFpbHksIFBvcENoYW5nZV9yYXRlLCBQb3BDaGFuZ2VfcmF0ZV9kYWlseSkgJT4lCiAgICBzdW1tYXJpc2UoYWNyb3NzKAogICAgLmNvbHMgPSBpcy5udW1lcmljLCAKICAgIC5mbnMgPSBsaXN0KE1lYW4gPSBtZWFuLCBTRCA9IHNkKSwgbmEucm0gPSBUUlVFLCAKICAgIC5uYW1lcyA9ICJ7Y29sfV97Zm59IgogICAgKSkKZGVtb19zdW0gCgpkZW1vX3N1bSA8LSBhcy5saXN0KGRlbW9fc3VtKQpgYGAKCiMjIyBBZ3RhIEJhbmQgU2l6ZQoKRGF0YSByZWdhcmRpbmcgY2FtcCBzaXplIG9mIEFndGEgaHVudGVyLWdhdGhlcmVycyB3YXMgb2J0YWluZWQgZnJvbSBhIHN0dWR5IG9mIDYxNSBpbmRpdmlkdWFscyBmcm9tIDE1IGNhbXBzIGluIGluIHRoZSBtdW5pY2lwYWxpdHkgb2YgUGFsYW5hbiwgdGhlIE5vcnRoZXJuIFBoaWxpcHBpbmVzIHB1Ymxpc2hlZCBieSBEeWJsZSBldCBhbC4gKDIwMjEpLgoKYGBge3J9CiMgSW1wb3J0IENhbXAgZGF0YSBmcm9tIE1hcmsgRHlibGUKY2FtcHMuZGF0YSA8LSByZWFkX2NzdigiQWd0YV9EYXRhL2NhbXBzLmNzdiIpCgpoZWFkKGNhbXBzLmRhdGEpCmBgYAoKCmBgYHtyfQojIEV4cGxvcmUgY2FtcCBzaXplCmhpc3QoY2FtcHMuZGF0YSRjYW1wX3RvdGFsKQoKY2FtcC5zaXplIDwtIGNhbXBzLmRhdGEgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKGNhbXBfdG90YWwpLAogICAgICAgICAgICBzZCA9IHNkKGNhbXBfdG90YWwpLAogICAgICAgICAgICBtaW4gPSBtaW4oY2FtcF90b3RhbCksCiAgICAgICAgICAgIG1heCA9IG1heChjYW1wX3RvdGFsKSwKICAgICAgICAgICAgdmFyID0gdmFyKGNhbXBfdG90YWwpKQpjYW1wLnNpemUKYGBgCgojIyMgUGF0aG9nZW4gWAoKRm9yIHRoZSBwdXJwb3NlIG9mIHRoaXMgaW52ZXN0aWdhdGlvbiB3ZSBmb3JtdWxhdGVkIGEgaHlwb3RoZXRpY2FsIHJlc3BpcmF0b3J5IHBhdGhvZ2VuLCByZWZlcnJlZCB0byBhcyBwYXRob2dlbiBYLiBUYWtpbmcgaW50byBhY2NvdW50IHRoZSBiaW9sb2dpY2FsIHRyYWRlLW9mZnMgYmV0d2VlbiBoaWdoIHRyYW5zbWlzc2liaWxpdHkgYW5kIGhpZ2ggcGF0aG9nZW5pY2l0eSwgcGF0aG9nZW4gWCB3YXMgZGVjaWRlZCB0byBiZSBoaWdobHkgaW5mZWN0aW91cyB3aXRoIGEgcmVsYXRpdmVseSBsb3cgY2FzZSBmYXRhbGl0eSByYXRlIG9mIDAuMDA1LiBUcmFuc21pc3Npb24gb2NjdXJyZWQgdmlhIGNsb3NlIGNvbnRhY3Qgd2l0aCBhbiBpbmZlY3RlZCBpbmRpdmlkdWFsLiBJbmZlY3Rpb24gd2FzIGNoYXJhY3RlcmlzZWQgYnkgYSBsYXRlbnQgcGVyaW9kIG9mIDUuNyBkYXlzIGZvbGxvd2VkIGJ5IGFuIGluZmVjdGlvdXMgcGVyaW9kIG9mIDUgZGF5cy4gSW5kaXZpZHVhbHMgd2hvIHJlY292ZXJlZCBmcm9tIGluZmVjdGlvbiB3ZXJlIGltbXVuZSBmb3IgMTAwIGRheXMsIGFmdGVyIHdoaWNoIGltbXVuaXR5IHdhbmVkIGFuZCBpbmRpdmlkdWFscyBiZWNhbWUgc3VzY2VwdGlibGUgdG8gcmUtaW5mZWN0aW9uLiBCYXNlZCBvbiB0aGVzZSBjaGFyYWN0ZXJpc3RpY3MsIHRoZSBwYXJhbWV0ZXJzIGluIHRhYmxlIDEgd2VyZSBhc3N1bWVkIGFuZCBpbnB1dCBpbnRvIHRoZSBmaW5hbCBtb2RlbHMuCgoqKlBhcmFtZXRlcioqIHwgKipSYXRlKiogICAgICAgICAgICAgIHwgKipWYWx1ZSoqCi0tLSAgICAgICAgICAgfCAtLS0gICAgICAgICAgICAgICAgICAgfCAtLS0gIAokXGJldGEkICAgICAgIHwgIFRyYW5zbWlzc2lvbiAgICAgICAgIHwgMC42IAokXHNpZ21hJCAgICAgIHwgIEluZmVjdGlvdXMgICAgICAgICAgIHwgMC4xNzUgCiRcZ2FtbWEkICAgICAgfCAgUmVjb3ZlcnkgICAgICAgICAgICAgfCAwLjIgCiRcYWxwaGEkICAgICAgfCAgRGVhdGggZnJvbSBJbmZlY3Rpb24gfCAwLjAwMQokXG9tZWdhJCAgICAgIHwgIFdhbmluZyBJbW11bml0eSAgICAgIHwgMC4wMQoKCgojIyBTaW5nbGUgUG9wdWxhdGlvbiBNb2RlbAoKVG8gaW52ZXN0aWdhdGUgdGhlIHBlcnNpc3RlbmNlIG9mIGEgaHlwb3RoZXRpY2FsIHJlc3BpcmF0b3J5IHBhdGhvZ2VuIGluIGh1bnRlci1nYXRoZXJlcnMsIHRoaXMgc3R1ZHkgY2hvc2UgdG8gc2ltdWxhdGUgZGlzZWFzZSB0cmFuc21pc3Npb24gdXNpbmcgYSBjb21wYXJ0bWVudCBtb2RlbCBhcHByb2FjaCBhcyBvdXRsaW5lZCBpbiB0aGUgaW50cm9kdWN0aW9uLiBUd28gbW9kZWxzIHdlcmUgY29uc3RydWN0ZWQgdG8gaW52ZXN0aWdhdGUgY29tcGFyZSB0aGUgZWZmZWN0IG9mIG1ldGFwb3B1bGF0aW9uIHN0cnVjdHVyZSBvbiBkaXNlYXNlIHBlcnNpc3RlbmNlLiBUaGlzIGZpcnN0IGRlc2NyaWJlcyB0aGUgdHJhbnNtaXNzaW9uIG9mIGEgcGF0aG9nZW4gd2l0aGluIGEgc2luZ2xlIHBvcHVsYXRpb24gd2l0aCBkZW1vZ3JhcGh5IGFuZCB3YW5pbmcgaW1tdW5pdHkgdG8gcmUtaW5mZWN0aW9uIG92ZXIgdGltZS4KCgpcCjxjZW50ZXI+CgoKIVsqRmlndXJlIDEgLSBGbG93IGRpYWdyYW0gb2YgU0VJUlMgbW9kZWwgb2YgdHJhbnNtaXNzaW9uKl0oUGxvdHMvU0VJUlNfRmxvd19EaWFncmFtLnBuZykKCgo8L2NlbnRlcj4KXApcClwKClxiZWdpbnthbGlnbip9CiAgXGZyYWN7e3tcbWF0aHJte2R9fVN9fXt7e1xtYXRocm17ZH19dH19ICYgPSBcdW5kZXJicmFjZSB7XG11IE59X3t7XG1hdGhybXtiaXJ0aH19fX4gLSB+XHVuZGVyYnJhY2Uge1xmcmFje1xiZXRhIFNJfXtOfX1fe3tcbWF0aHJte2luZmVjdGlvbn19fX5+ICsgXHVuZGVyYnJhY2Uge1xvbWVnYSBSfV97e1xtYXRocm17bG9zdH19XCx7XG1hdGhybXtpbW11bml0eX19fSAtIFx1bmRlcmJyYWNlIHtcbXUgU31fe3tcbWF0aHJte2RlYXRofX19IFxcCiAgXGZyYWN7e3tcbWF0aHJte2R9fUV9fXt7e1xtYXRocm17ZH19dH19ICYgPSBcdW5kZXJicmFjZSB7XGZyYWN7XGJldGEgU0l9e059fV97e1xtYXRocm17aW5mZWN0aW9ufX19fiAtIH5cdW5kZXJicmFjZSB7XHNpZ21hIEV9X3t7XG1hdGhybXtsYXRlbmN5fX19IC0gXHVuZGVyYnJhY2Uge1xtdSBFfV97e1xtYXRocm17ZGVhdGh9fX0gXFwKICBcZnJhY3t7e1xtYXRocm17ZH19SX19e3t7XG1hdGhybXtkfX10fX0gJiA9IFx1bmRlcmJyYWNlIHtcc2lnbWEgRX1fe3tcbWF0aHJte2xhdGVuY3l9fX0gLSBcdW5kZXJicmFjZSB7XGdhbW1hIEl9X3t7XG1hdGhybXtyZWNvdmVyeX19fSAtIH5cdW5kZXJicmFjZSB7XGxlZnQoIHtcbXUgKyBcYWxwaGEgfSBccmlnaHQpSX1fe3tcbWF0aHJte2RlYXRofX19IFxcCiAgXGZyYWN7e3tcbWF0aHJte2R9fVJ9fXt7e1xtYXRocm17ZH19dH19ICYgPSBcdW5kZXJicmFjZSB7XGdhbW1hIEl9X3t7XG1hdGhybXtyZWNvdmVyeX19fSAtIFx1bmRlcmJyYWNlIHtcb21lZ2EgUn1fe3tcbWF0aHJte2xvc3R9fVwge1xtYXRocm17aW1tdW5pdHl9fX0gLSBcdW5kZXJicmFjZSB7XG11IFJ9X3t7XG1hdGhybXtkZWF0aH19fQpcZW5ke2FsaWduKn0KClwKXAoKCldoZXJlIHRyYW5zbWlzc2lvbiBpcyBmcmVxdWVuY3kgZGVwZW5kZW50LCAke1xmcmFje1xiZXRhIFNJfXtOfX0kLCAkXGZyYWN7MX17XHNpZ21hfSQgaXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBsYXRlbnQgcGhhc2UsICRcZnJhY3sxfXtcZ2FtbWF9JCBpcyB0aGUgZHVyYXRpb24gb2YgaW5mZWN0aW9uLCAkXGZyYWN7MX17XG9tZWdhfSQgaXMgdGhlIGR1cmF0aW9uIG9mIGltbXVuaXR5IGFuZCBkZWF0aCBmcm9tIGluZmVjdGlvbiBvY2N1cnMgYXQgdGhlIHJhdGUgJFxhbHBoYSQuIEluZGl2aWR1YWxzIGNhbiBiZSBib3JuIGludG8gUyBhbmQgZGllIG5hdHVyYWxseSBmcm9tIGFueSBjb21wYXJ0bWVudCBhdCBhIHJhdGUgb2YgJFxtdSQuCgoKCiMjIyBNb2RlbCBTZXQtdXAKCk1vZGVsIHdhcyBzZXQgdXAgd2l0aCBhIHNpbmdsZSByYW5kb21seSBzZWxlY3RlZCBjYW1wIHNpemUgd2l0aCBhIHNpbmdsZSBpbmZlY3RlZCBpbmRpdmlkdWFsIGFuZCBwYXJhbWV0ZXJzIGZvciBwYXRob2dlbiBYLiAKCmBgYHtyfQojIERlZmluZSBQYXJhbWVudGVycwpOIDwtICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgUG9wdWxhdGlvbiBzaXplCmluaXRpYWxfaW5mZWN0ZWQgPC0gIDEgICAgIyBJbml0aWFsIGluZmVjdGVkCnNpbU5hbWUgPC0gIlNFSVJTIG1vZGVsIiAgICAgICAjIFNpbXVsYXRpb24gbmFtZQp0ZiA8LSAzNjUqMwoKI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtcyA8LSBsaXN0KAogIGJldGEgPSAwLjYsCiAgc2lnbWEgPSAwLjE3NSwgICAgICAgICAgICAgICAgICAgICAgICAgICMgRSB0byBJIHJhdGUKICBnYW1tYSA9IDAuMiwgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEkgdG8gUiByYXRlCiAgb21lZ2EgPSAxLzEwMCwgICAgICAgICAgICAgICAgICAgICAgICAgIyBSIHRvIFMgcmF0ZQogIG11ID0gZGVtb19zdW0kQmlydGhfcmF0ZV9kYWlseV9NZWFuLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRoL2RlYXRoIHJhdGUgcGVyIHBlcnNvbiBwZXIgZGF5CiAgYWxwaGEgPSAxLzEwMDApIAoKI0NyZWF0ZSB0aGUgbmFtZWQgaW5pdGlhbCBzdGF0ZSB2ZWN0b3IgZm9yIHRoZSBVLXBhdGNoIHN5c3RlbS4KCngwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgpuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKIyBEZWZpbmUgdGhlIHN0YXRlIGNoYW5nZSBtYXRyaXggZm9yIGEgc2luZ2xlIHBhdGNoCm51IDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICAwLCAgMCwgIyBFCiAgICAgICAgICAgICAgICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsIC0xLCAjIEkKICAgICAgICAgICAgICAgIDAsICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICMgUiAKICAgICAgICAgICAgICAgIDAsICAwLCAgMCwgIDAsICsxLCAtMSAsLTEsIC0xLCAtMSwgLTEpLCAjIE4KICAgICAgICAgICAgIG5yb3c9NSxieXJvdz1UUlVFKQoKIyBEZWZpbmUgcHJvcGVuc2l0eSBmdW5jdGlvbnMKYSA8LWMoCiAgICAgICAgcGFzdGUwKCIoYmV0YSpJL04pKlMiKSwgIyBJbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoInNpZ21hKkUiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJlY29tZXMgaW5mZWNpb3VzCiAgICAgICAgcGFzdGUwKCJnYW1tYSpJIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBSZWNvdmVyeSBmcm9tIGluZmVjdGlvbgogICAgICAgIHBhc3RlMCgib21lZ2EqUiIpLCAgICAgICAjIExvc3Mgb2YgaW1tdW5pdHkKICAgICAgICBwYXN0ZTAoIm11Kk4iKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGhzCiAgICAgICAgcGFzdGUwKCJtdSpTIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFMpCiAgICAgICAgcGFzdGUwKCJtdSpFIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEUpCiAgICAgICAgcGFzdGUwKCJtdSpJIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEkpCiAgICAgICAgcGFzdGUwKCJtdSpSIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFIpCiAgICAgICAgcGFzdGUwKCJhbHBoYSpJIikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgZnJvbSBpbmZlY3Rpb24KICAgICAgICAKICAgICAgKQoKYGBgCgpEZWZpbmUgZnVuY3Rpb25zIHRvIGNhbGN1bGF0ZSBSMCBhbmQgZXhwZWN0ZWQgbnVtYmVyIG9mIHN1c2NlcHRpYmxlcyBhdCBlcXVpbGlicml1bSwgYW5kIGNyaXRpY2FsIGNvbW11bml0eSBzaXplIChEaWVrbWFubiBldCBhbC4sIDIwMTIpLgoKYGBge3J9CiBSMCA8LSBmdW5jdGlvbihwYXJtcykgewogICAocGFybXMkc2lnbWEvKHBhcm1zJHNpZ21hICsgcGFybXMkbXUpKSAqIChwYXJtcyRiZXRhL3Bhcm1zJGdhbW1hICsgcGFybXMkbXUgKyBwYXJtcyRhbHBoYSkKIH0gCiAgCkVJRSA8LSBmdW5jdGlvbihSMCwgcGFybXMpIHsKICB5ID0gKChSMCAtIDEpICogcGFybXMkb21lZ2EpIC8gKHBhcm1zJGdhbW1hICogUjApCiAgcmV0dXJuKHkpCn0KCkNDUyA8LSBmdW5jdGlvbihpbmZlY3Rpb3VzX3BlcmlvZCwgUjApIHsKICB4ID0gaW5mZWN0aW91c19wZXJpb2QvKDIzKjM2NSkgICAgICAgICAgICMgQXZnIGxpZmUgbGlmZSBleHBleGN0YW5jeSBvZiAyMyAoR3VydmVuIGV0IGFsLiAyMDA3KQogIHkgPSAxLygoeF4yKSooKDEtKDEvUjApKV4yKSkKICByZXR1cm4oeSkKfQpgYGAKCiMjIyBDYWxjdWxhdGUgRXBpZGVtaWMgU3RhdGlzdGljcwo8PDw8PDw8IEhFQUQKVGhlIGV4cGVjdGVkIG51bWJlciBvZiBzZWNvbmRhcnkgY2FzZXMgZnJvbSBhIHNpbmdsZSBpbmZlY3RlZCBpbmRpdmlkdWFsIGluIGFuIGVudGlyZWx5IHN1c2NlcHRpYmxlIHBvcHVsYXRpb24sIGFsc28ga25vd24gYXMgdGhlIGJhc2ljIHJlcHJvZHVjdGlvbiBudW1iZXIgKCRSXzAkKSwgd2FzIGNhbGN1bGF0ZWQgZm9yIHBhdGhvZ2VuIFggaW4gYm90aCB0aGUgc2luZ2xlIGFuZCBtZXRhIHBvcHVsYXRpb24gbW9kZWwuIEluIHRoZSBzaW5nbGUgcG9wdWxhdGlvbiBTRUlSUyBtb2RlbCwgJFJfMCQgbWF5IGJlIGVzdGltYXRlZH4oQmrDuHJuc3RhZCwgMjAyMyk6CgpcYmVnaW57ZXF1YXRpb259ICAgICAgIAogICAgUl8wID0gXGZyYWN7XHNpZ21hfXtcc2lnbWEgKyBcbXV9KlxmcmFje1xiZXRhfXtcZ2FtbWEgKyBcbXUgKyBcYWxwaGF9ClxlbmR7ZXF1YXRpb259CgpJbiB0aGUgbWV0YXBvcHVsYXRpb24gbW9kZWwsIHRoZSBzYW1lIGVxdWF0aW9uIHdhcyBhcHBsaWVkIGFjcm9zcyB0aGUgbmV4dC1nZW5lcmF0aW9uIG1hdHJpeCBhbmQgdGhlIGVpZ2VudmFsdWUgY2FsY3VsYXRlZCB0byBpbmZlciAkUl8wJCBhY3Jvc3MgYWxsIHBhdGNoZXMuIFRvIHByb3ZpZGUgYW4gZXN0aW1hdGUgZm9yIHRoZSBudW1iZXIgb2YgaW5kaXZpZHVhbHMgcmVxdWlyZWQgdG8gc3VzdGFpbiBlbmRlbWljIHNwcmVhZCBvZiBwYXRob2dlbiBYIGluIGEgc2luZ2xlIHBvcHVsYXRpb24sIEkgY2FsY3VsYXRlZCB0aGUgY3JpdGljYWwgY29tbXVuaXR5IHNpemUgKENDUykgKERpZWttYW5uLCBIZWVzdGVyYmVlaywgYW5kIEJyaXR0b24sIDIwMTIpOgoKXGJlZ2lue2VxdWF0aW9ufSAgICAgICAgCiAgICBOX2MgPSBcZnJhY3sxfXtcZXBzaWxvbl4yKDEtXGZyYWN7MX17Ul8wfSleMn0KXGVuZHtlcXVhdGlvbn0KCldoZXJlICROX2MkIGlzIHRoZSBDQ1MgYWJvdmUgd2hpY2ggZW5kZW1pYyBzcHJlYWQgbWF5IGJlIHN1c3RhaW5lZCBhbmQgJFxlcHNpbG9uJCBpcyB0aGUgcmF0aW8gb2YgdGhlIGF2ZXJhZ2UgbGVuZ3RoIG9mIHRoZSBpbmZlY3Rpb3VzIHBlcmlvZCB0byB0aGUgbGlmZSBleHBlY3RhbmN5IG9mIHRoZSBob3N0LiBUaGUgQ0NTIHJlcHJlc2VudHMgdGhlIG1pbmltdW0gcG9wdWxhdGlvbiBzaXplIHJlcXVpcmVkIHRvIHByZXZlbnQgZGlzZWFzZSBleHRpbmN0aW9uLiBBIGNydWRlIGF2ZXJhZ2UgbGlmZSBleHBlY3RhbmN5IG9mIDIzIHllYXJzIHdhcyB1c2VkIHRvIGRlc2NyaWJlIEFndGEgaHVudGVyLWdhdGhlcmVycyBhcyBwdWJsaXNoZWQgYnl+IEd1cnZlbiBhbmQgS2FwbGFuICgyMDA3KS4KClRoZSBleHBlY3RlZCBwcm9wb3J0aW9uIG9mIGluZmVjdGVkIGluZGl2aWR1YWxzIGF0IGVuZGVtaWMgZXF1aWxpYnJpdW0sICRJXiokLCB3YXMgYWxzbyBjYWxjdWxhdGVkIGluIHRoZSBzaW5nbGUgcG9wdWxhdGlvbiBtb2RlbH4oS2VlbGluZyBhbmQgUm9oYW5pLCAyMDA4KToKClxiZWdpbntlcXVhdGlvbn0gICAgICAgICAgICAKICAgIEleKiA9IFxmcmFjeyhSXzAgLSAxKVxvbWVnYX17XGdhbW1hIFJfMH0KXGVuZHtlcXVhdGlvbn0KCj09PT09PT0KPj4+Pj4+PiA2NzI3MjgwMjhmMThiMmZjMjI0MzIyOTkzZDI0NWM5YTZlZTcxYmYxCmBgYHtyfQoKIyBDYWxjdWxhdGUgUjAsIGV4cGVjdGVkIG51bWJlciBvZiBpbmZlY3RlZHMgYXQgZXF1aWxpYnJpdW0sIG1hZ25pdHVkZSBvZiBvc2NpbGxhdGlvbiBhbmQgQ0NTClIwX3NpbmdsZSA8LSBSMChwYXJtcykKUjBfc2luZ2xlCgpFSUVfc2luZ2xlIDwtIEVJRShSMF9zaW5nbGUsIHBhcm1zKSAjIHByb3BvcnRpb24gb2YgZXhwZWN0ZWQgaW5mZWN0ZWRzIGF0IGVxdWlsaWJyaXVtCkVJRV9zaW5nbGUKCmV4cGV4dGVkX2luZmVjdGVkcyA8LSBFSUVfc2luZ2xlKk4gIyBudW1iZXIgb2YgZXhwZWN0ZWQgaW5mZWN0ZWRzIGF0IGVxdWlsaWJyaXVtCmV4cGV4dGVkX2luZmVjdGVkcwoKc3FydChOKSAjIG1hZ25pdHVkZSBvZiBvc2NpbGxhdGlvbnMgCgpDQ1Nfc2luZ2xlIDwtIENDUyhpbmZlY3Rpb3VzX3BlcmlvZCA9IDUsIFIwID0gUjBfc2luZ2xlKSAjIEF2ZXJhZ2UgbGlmZSBleHBlY3RhbmN5IGFzIHBlciBLYXBsYW4gKGNydWRlKQpDQ1Nfc2luZ2xlCmBgYAojIyMgUGxvdCBDQ1MgYnkgaW5mZWN0aW91cyBwZXJpb2QgYW5kIFIwCjw8PDw8PDwgSEVBRAoKUGFyYW1ldGVyIHNwYWNlIG9mIENDUyBlcXVhdGlvbiB3YXMgZXhwbG9yZWQgd2l0aCBpbmZlY3Rpb3VzIHBlcmlvZCByYW5naW5nIGZyb20gNSB0byAzNjUgZGF5cyBhbmQgJFJfMCQgcmFuZ2luZyBmcm9tIDEuMSB0byA1LiAKCmBgYHtyfQppbmZlY3Rpb3VzX3BlcmlvZHMgPC0gc2VxKDUsIDM2NSwgMTApCgo9PT09PT09CmBgYHtyfQppbmZlY3Rpb3VzX3BlcmlvZHMgPC0gc2VxKDUsIDM2NSwgMTApCgo+Pj4+Pj4+IDY3MjcyODAyOGYxOGIyZmMyMjQzMjI5OTNkMjQ1YzlhNmVlNzFiZjEKUjBfc2VxIDwtIHNlcSgxLjEsNSwwLjIpCgp4ID0gaW5mZWN0aW91c19wZXJpb2RzCgp5ID0gUjBfc2VxCgp6ID0gbG9nMTAob3V0ZXIoeCwgeSwgQ0NTKSkKCnBlcnNwM0QoeCwgeSwgeiwKICAgICAgICB6bGltID0gYygwLDEwKSwKICAgICAgICB4bGltID0gYyg1LCAzNjUpLAogICAgICAgIHlsaW0gPSBjKDEsIDUpLAogICAgICAgIHhsYWIgPSAiSW5mZWN0aW91cyBQZXJpb2QgKGRheXMpIiwKICAgICAgICB5bGFiID0gIkJhc2ljIFJlcHJvZHVjdGl2ZSBudW1iZXIgKFIwKSIsCiAgICAgICAgemxhYiA9ICJsb2cxMChDcml0Y2FsIENvbW11bml0eSBTaXplKSIsCiAgICAgICAgc2hhZGUgPSAgMC4xNSwgdGhldGEgPSAxNDAsIHBoaSA9IDMwLCBleHBhbmQgPSAwLjYsCiAgICAgICAgdGlja3R5cGUgPSAiZGV0YWlsZWQiKQpgYGAKCgoKIyMjIFJ1biBTaW5nbGUgUG9wdWxhdGlvbiBNb2RlbApgYGB7cn0KIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyMSkKb3V0IDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtcywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKSAKCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhIDwtIG91dCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKc2luZ2xlX3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZShhbHBoYT0wLjgpKwogIGxhYnMoeD0iVGltZSAoRGF5cykiLAogICAgICAgeT0iTnVtYmVyIG9mIEluZGl2aWR1YWxzIiwgCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZXhwZXh0ZWRfaW5mZWN0ZWRzLCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArCiAgdGhlbWVfYncoKQoKc2luZ2xlX3Bsb3QKCiNnZ3NhdmUoZmlsZW5hbWUgPSAic2luZ2xlX3Bsb3QucGRmIiwgCiAgICAgICAjcGxvdCA9IHNpbmdsZV9wbG90LAogICAgICAgI2RldmljZSA9ICJwZGYiLAogICAgICAgI3dpZHRoID0gNywgCiAgICAgICAjaGVpZ2h0ID0gMywKICAgICAgICNwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvUGxvdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscyIpCmBgYAoKYGBge3J9CnBsb3RfZGF0YSAlPiUKICBmaWx0ZXIoc3RhdGUgPT0gIkkiKSAlPiUKICBzbGljZV9tYXgoY291bnQpCmBgYApPdXRicmVhayBwZWFrZWQgYXQgZGF5IDI1IHdpdGggMTQgaW5mZWN0ZWQgaW5kaXZpZHVhbHMuCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3QgPC0gbGlzdCgpCnNpbV9saXN0IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBzZXQuc2VlZChpKQogIG91dF8xMDAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YSA8LSBvdXRfMTAwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdFtbaV1dIDwtIHNpbV9kYXRhCn0KCnNpbV9vdXRwdXQgPC0gYmluZF9yb3dzKHNpbV9saXN0KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0IDwtIHNpbV9vdXRwdXQgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpoZWFkKHNpbV9vdXRwdXQpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnkgPC0gc2ltX291dHB1dCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnkKYGBgCgojIyMgVmFyeWluZyB3YWluaW5nIGltbXVuaXR5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQpXYW5pbmcgaW1tdW5pdHkgd2FzIHRob3VnaHQgdG8gcGxheSBhbiBpbXBvcnRhbnQgcm9sZSBpbiB0aGUgcGVyc2lzdGVuY2Ugb2YgcGF0aG9nZW4gWCBzbyB3ZSBpbmNyZW1lbnRhbGx5IGluY3JlYXNlZCB0aGUgZHVyYXRpb24gb2YgaW1tdW5pdHkgKGJ5IGRlY3JlYXNpbmcgJFxvbWVnYSQpIGFuZCBjYWxjdWxhdGVkIHRoZSBwcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzIGluIDEwMDAgc3RvY2hhc3RpYyBzaW11bGF0aW9ucy4gRHVyYXRpb24gb2YgaW1tdW5pdHkgd2FzIGluY3JlYXNlZCBmcm9tIDEgZGF5IHRvIGEgeWVhci4KCiMjIyMgMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzAgPC0gcGFybXMKcGFybXNfMCRvbWVnYSA8LSAwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8wIDwtIG91dF8wJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8wCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMCA8LSBsaXN0KCkKc2ltX2xpc3RfMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzAgPC0gb3V0XzEwMF8wJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8wW1tpXV0gPC0gc2ltX2RhdGFfMAp9CgpzaW1fb3V0cHV0XzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMCA8LSBzaW1fb3V0cHV0XzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8wIDwtIHNpbV9vdXRwdXRfMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAwKQpzaW1fc3VtbWFyeV8wCmBgYAoKCgoKIyMjIyAxIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMSA8LSBwYXJtcwpwYXJtc18xJG9tZWdhIDwtIDEKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc18xLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzEgPC0gb3V0XzEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzEKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xIDwtIGxpc3QoKQpzaW1fbGlzdF8xIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMSA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMSA8LSBvdXRfMTAwXzEkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzFbW2ldXSA8LSBzaW1fZGF0YV8xCn0KCnNpbV9vdXRwdXRfMSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xIDwtIHNpbV9vdXRwdXRfMSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzEgPC0gc2ltX291dHB1dF8xICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEpCnNpbV9zdW1tYXJ5XzEKYGBgCgoKCgoKIyMjIyAzIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMyA8LSBwYXJtcwpwYXJtc18zJG9tZWdhIDwtIDEvMwoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzMgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzMsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMyA8LSBvdXRfMyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzMsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMwpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzMgPC0gbGlzdCgpCnNpbV9saXN0XzMgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zIDwtIG91dF8xMDBfMyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM1tbaV1dIDwtIHNpbV9kYXRhXzMKfQoKc2ltX291dHB1dF8zIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzMgPC0gc2ltX291dHB1dF8zICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMyA8LSBzaW1fb3V0cHV0XzMgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zKQpzaW1fc3VtbWFyeV8zCmBgYAoKIyMjIyA3IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNyA8LSBwYXJtcwpwYXJtc183JG9tZWdhIDwtIDEvNwoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzcgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzcsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfNyA8LSBvdXRfNyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF83IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzcsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfNwpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzcgPC0gbGlzdCgpCnNpbV9saXN0XzcgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF83IDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzcsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83IDwtIG91dF8xMDBfNyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfN1tbaV1dIDwtIHNpbV9kYXRhXzcKfQoKc2ltX291dHB1dF83IDwtIGJpbmRfcm93cyhzaW1fbGlzdF83KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzcgPC0gc2ltX291dHB1dF83ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF83CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNyA8LSBzaW1fb3V0cHV0XzcgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83KQpzaW1fc3VtbWFyeV83CmBgYAoKIyMjIyAxMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEwIDwtIHBhcm1zCnBhcm1zXzEwJG9tZWdhIDwtIDEvMTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xMCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTAgPC0gb3V0XzEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzEwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzEwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTAgPC0gbGlzdCgpCnNpbV9saXN0XzEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xMCA8LSBvdXRfMTAwXzEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xMFtbaV1dIDwtIHNpbV9kYXRhXzEwCn0KCnNpbV9vdXRwdXRfMTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzEwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzEwIDwtIHNpbV9vdXRwdXRfMTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzEwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTAgPC0gc2ltX291dHB1dF8xMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwKQpzaW1fc3VtbWFyeV8xMApgYGAKCiMjIyMgMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18yMCA8LSBwYXJtcwpwYXJtc18yMCRvbWVnYSA8LSAxLzIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMjAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzIwIDwtIG91dF8yMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8yMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8yMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8yMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzIwIDwtIGxpc3QoKQpzaW1fbGlzdF8yMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzIwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMjAgPC0gb3V0XzEwMF8yMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMjBbW2ldXSA8LSBzaW1fZGF0YV8yMAp9CgpzaW1fb3V0cHV0XzIwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8yMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8yMCA8LSBzaW1fb3V0cHV0XzIwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8yMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzIwIDwtIHNpbV9vdXRwdXRfMjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yMCkKc2ltX3N1bW1hcnlfMjAKYGBgCgojIyMjIDMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMzAgPC0gcGFybXMKcGFybXNfMzAkb21lZ2EgPC0gMS8zMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzMwIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc18zMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zMCA8LSBvdXRfMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zMCA8LSBsaXN0KCkKc2ltX2xpc3RfMzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zMCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18zMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzMwIDwtIG91dF8xMDBfMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzMwW1tpXV0gPC0gc2ltX2RhdGFfMzAKfQoKc2ltX291dHB1dF8zMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMzAgPC0gc2ltX291dHB1dF8zMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zMCA8LSBzaW1fb3V0cHV0XzMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzApCnNpbV9zdW1tYXJ5XzMwCmBgYAoKIyMjIyA0MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzQwIDwtIHBhcm1zCnBhcm1zXzQwJG9tZWdhIDwtIDEvNDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF80MCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfNDAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfNDAgPC0gb3V0XzQwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzQwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzQwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzQwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNDAgPC0gbGlzdCgpCnNpbV9saXN0XzQwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNDAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNDAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV80MCA8LSBvdXRfMTAwXzQwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF80MFtbaV1dIDwtIHNpbV9kYXRhXzQwCn0KCnNpbV9vdXRwdXRfNDAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzQwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzQwIDwtIHNpbV9vdXRwdXRfNDAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzQwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNDAgPC0gc2ltX291dHB1dF80MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzQwKQpzaW1fc3VtbWFyeV80MApgYGAKCiMjIyMgNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc181MCA8LSBwYXJtcwpwYXJtc181MCRvbWVnYSA8LSAxLzUwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfNTAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzUwIDwtIG91dF81MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF81MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV81MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF81MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzUwIDwtIGxpc3QoKQpzaW1fbGlzdF81MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzUwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNTAgPC0gb3V0XzEwMF81MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNTBbW2ldXSA8LSBzaW1fZGF0YV81MAp9CgpzaW1fb3V0cHV0XzUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF81MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF81MCA8LSBzaW1fb3V0cHV0XzUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF81MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzUwIDwtIHNpbV9vdXRwdXRfNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS81MCkKc2ltX3N1bW1hcnlfNTAKYGBgCgojIyMjIDYwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNjAgPC0gcGFybXMKcGFybXNfNjAkb21lZ2EgPC0gMS82MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzYwIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc182MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV82MCA8LSBvdXRfNjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfNjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfNjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfNjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF82MCA8LSBsaXN0KCkKc2ltX2xpc3RfNjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF82MCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc182MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzYwIDwtIG91dF8xMDBfNjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzYwW1tpXV0gPC0gc2ltX2RhdGFfNjAKfQoKc2ltX291dHB1dF82MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNjAgPC0gc2ltX291dHB1dF82MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV82MCA8LSBzaW1fb3V0cHV0XzYwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNjApCnNpbV9zdW1tYXJ5XzYwCmBgYAoKIyMjIyA3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzcwIDwtIHBhcm1zCnBhcm1zXzcwJG9tZWdhIDwtIDEvNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF83MCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfNzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfNzAgPC0gb3V0XzcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzcwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNzAgPC0gbGlzdCgpCnNpbV9saXN0XzcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNzAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83MCA8LSBvdXRfMTAwXzcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF83MFtbaV1dIDwtIHNpbV9kYXRhXzcwCn0KCnNpbV9vdXRwdXRfNzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzcwIDwtIHNpbV9vdXRwdXRfNzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNzAgPC0gc2ltX291dHB1dF83MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcwKQpzaW1fc3VtbWFyeV83MApgYGAKCiMjIyMgODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc184MCA8LSBwYXJtcwpwYXJtc184MCRvbWVnYSA8LSAxLzgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfODAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzgwIDwtIG91dF84MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF84MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV84MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF84MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzgwIDwtIGxpc3QoKQpzaW1fbGlzdF84MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzgwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfODAgPC0gb3V0XzEwMF84MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfODBbW2ldXSA8LSBzaW1fZGF0YV84MAp9CgpzaW1fb3V0cHV0XzgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF84MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF84MCA8LSBzaW1fb3V0cHV0XzgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF84MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzgwIDwtIHNpbV9vdXRwdXRfODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfODAKYGBgCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE1MCA8LSBwYXJtcwpwYXJtc18xNTAkb21lZ2EgPC0gMS8xNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNTAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzE1MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNTAgPC0gb3V0XzE1MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE1MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE1MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTUwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzE1MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE1MCA8LSBvdXRfMTAwXzE1MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTUwW1tpXV0gPC0gc2ltX2RhdGFfMTUwCn0KCnNpbV9vdXRwdXRfMTUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTUwIDwtIHNpbV9vdXRwdXRfMTUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNTAgPC0gc2ltX291dHB1dF8xNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNTApCnNpbV9zdW1tYXJ5XzE1MApgYGAKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTgwIDwtIHBhcm1zCnBhcm1zXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzEwMCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMTgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE4MCA8LSBvdXRfMTgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE4MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTgwIDwtIGxpc3QoKQpzaW1fbGlzdF8xODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xODAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTgwIDwtIG91dF8xMDBfMTgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xODBbW2ldXSA8LSBzaW1fZGF0YV8xODAKfQoKc2ltX291dHB1dF8xODAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE4MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xODAgPC0gc2ltX291dHB1dF8xODAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE4MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE4MCA8LSBzaW1fb3V0cHV0XzE4MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE4MCkKc2ltX3N1bW1hcnlfMTgwCmBgYAoKCiMjIyMgMzY1IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMzY1IDwtIHBhcm1zCnBhcm1zXzM2NSRvbWVnYSA8LSAxLzM2NQoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzM2NSA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMzY1LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzM2NSA8LSBvdXRfMzY1JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzM2NSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zNjUsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMzY1CmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMzY1IDwtIGxpc3QoKQpzaW1fbGlzdF8zNjUgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKIE5fYSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCxOX2EpCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMzY1IDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzM2NSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzM2NSA8LSBvdXRfMTAwXzM2NSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMzY1W1tpXV0gPC0gc2ltX2RhdGFfMzY1Cn0KCnNpbV9vdXRwdXRfMzY1IDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zNjUpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMzY1IDwtIHNpbV9vdXRwdXRfMzY1ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zNjUKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zNjUgPC0gc2ltX291dHB1dF8zNjUgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5XzM2NQpgYGAKCgoKIyMjIyBSZXN1bHRzCmBgYHtyfQp3YW5pbmdfcmVzdWx0c19zaW5nbGUgPC0gc2ltX3N1bW1hcnkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzEpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzQwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV82MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzcwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfODApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xMDApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zNjUpICU+JQogIG11dGF0ZShpbW11bml0eV9kdXJhdGlvbiA9IDEvb21lZ2EpICU+JQogIGFycmFuZ2UoaW1tdW5pdHlfZHVyYXRpb24pICU+JQogIG11dGF0ZShtb2RlbD0ic2luZ2xlIiwKICAgICAgICAgcGF0Y2hlcyA9IDEpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHNfc2luZ2xlLCBmaWxlID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscy9SZXN1bHRzL3dhbmluZ19yZXN1bHRzX3NpbmdsZS5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfc2luZ2xlCgpgYGAKCmBgYHtyfQpnZ3Bsb3Qod2FuaW5nX3Jlc3VsdHNfc2luZ2xlLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIHN1bV9wZXJzaXN0KSkgKwogIGdlb21fbGluZSgpKwogIGdlb21fcG9pbnQoKSsKICB0aGVtZV9idygpCmBgYAoKCgoKIyMgNy1QYXRjaCBNZXRhcG9wdWxhdGlvbiBNb2RlbCAKClJlY2VudCBzdHVkaWVzIGhhdmUgc3VnZ2VzdGVkIHRoYXQgcHJlLWFncmljdWx0dXJhbCBodW50ZXItZ2F0aGVyZXJzIGRpZCBub3QgbGl2ZSBpbiBzbWFsbCBpc29sYXRlZCBncm91cHMgYnV0IGZyb21lZCBpbnRlcmNvbm5lY3RlZCBtdWx0aS1jYW1wIG5ldHdvcmtzLiBUbyBpbnZlc3RpZ2F0ZSB0aGlzIHdlIGJ1aWx0IGEgc2Vjb25kIHBvcHVsYXRpb24gdGhhdCBhY2NvdW50cyBmb3IgbWV0YXBvcHVsYXRpb24gc3RydWN0dXJlIG9mIGh1bnRlci1nYXRoZXJlcnMuIFRoZSBzZWNvbmQgbW9kZWwgZm9sbG93cyBhbiBhbG1vc3QgaWRlbnRpY2FsIGZvcm1hdCBhcyB0aGUgc2luZ2xlIHBvcHVsYXRpb24gbW9kZWwsIGJ1dCBpbnN0ZWFkIGhhcyBiZWVuIGV4cGFuZGVkIHRvIGFjY29tbW9kYXRlIHRoZSBtZXRhcG9wdWxhdGlvbiBzdHJ1Y3R1cmUgb2YgbXVsdGktYmFuZCBodW50ZXItZ2F0aGVyZXIgZ3JvdXBzOgoKClxiZWdpbnthbGlnbip9ClxmcmFje3t7XG1hdGhybXtkfX1TfX17e3tcbWF0aHJte2R9fXR9fSAmID0gXHVuZGVyYnJhY2Uge1xtdV9pIE5faX1fe3tcbWF0aHJte2JpcnRofX19fiAtIH5cdW5kZXJicmFjZSB7XGJpZ2dsKFxmcmFje1xiZXRhX3tpaX0gSV9pfXtOX2l9ICsgXGZyYWN7XGJldGFfe2ppfSBJX2p9IHtOX2p9ICsgLi4uIFxiaWdncilTX2l9X3t7XG1hdGhybXtpbmZlY3Rpb259fX1+fiArIFx1bmRlcmJyYWNlIHtcb21lZ2FfaSBSX2l9X3t7XG1hdGhybXtsb3N0fX1cLHtcbWF0aHJte2ltbXVuaXR5fX19IC0gXHVuZGVyYnJhY2Uge1xtdV9pIFNfaX1fe3tcbWF0aHJte2RlYXRofX19IFxcClxmcmFje3t7XG1hdGhybXtkfX1FfX17e3tcbWF0aHJte2R9fXR9fSAmID0gXHVuZGVyYnJhY2Uge1xiaWdnbChcZnJhY3tcYmV0YV97aWl9IElfaX17Tl9pfSArIFxmcmFje1xiZXRhX3tqaX0gSV9qfSB7Tl9qfSArIC4uLiBcYmlnZ3IpU19pfV97e1xtYXRocm17aW5mZWN0aW9ufX19fiAtIH5cdW5kZXJicmFjZSB7XHNpZ21hX2kgRV9pfV97e1xtYXRocm17bGF0ZW5jeX19fSAtIFx1bmRlcmJyYWNlIHtcbXVfaSBFX2l9X3t7XG1hdGhybXtkZWF0aH19fSBcXApcZnJhY3t7e1xtYXRocm17ZH19SX19e3t7XG1hdGhybXtkfX10fX0gJiA9IFx1bmRlcmJyYWNlIHtcc2lnbWFfaSBFX2l9X3t7XG1hdGhybXtsYXRlbmN5fX19IC0gXHVuZGVyYnJhY2Uge1xnYW1tYV9pIElfaX1fe3tcbWF0aHJte3JlY292ZXJ5fX19IC0gflx1bmRlcmJyYWNlIHtcbGVmdCgge1xtdV9pICsgXGFscGhhX2kgfSBccmlnaHQpSV9pfV97e1xtYXRocm17ZGVhdGh9fX0gXFwKXGZyYWN7e3tcbWF0aHJte2R9fVJ9fXt7e1xtYXRocm17ZH19dH19ICYgPSBcdW5kZXJicmFjZSB7XGdhbW1hX2kgSV9pfV97e1xtYXRocm17cmVjb3Zlcnl9fX0gLSBcdW5kZXJicmFjZSB7XG9tZWdhX2kgUl9pfV97e1xtYXRocm17bG9zdH19XCB7XG1hdGhybXtpbW11bml0eX19fSAtIFx1bmRlcmJyYWNlIHtcbXVfaSBSX2l9X3t7XG1hdGhybXtkZWF0aH19fQpcZW5ke2FsaWduKn0KClRoZXNlIGNvdXBsZWQgZGlmZmVyZW50aWFsIGVxdWF0aW9ucyBkZXNjcmliZSB0aGUgd2l0aGluLXBhdGNoIFNFSVJTLXR5cGUgZHluYW1pY3Mgb2YgdGhlICRpJHRoIHBhdGNoIHdoZXJlIHRoZSBmb3JjZSBvZiBpbmZlY3Rpb24gaXMgZHJpdmVuIGJ5IGNvbnRhY3Qgb2Ygc3VzY2VwdGlibGVzIHdpdGggaW5mZWN0ZWRzIHdpdGhpbiB0aGUgJGkkdGggcGF0Y2ggYW5kIGluIHRoZSAkaiR0aCBvdGhlciBwYXRjaGVzLiBCb3RoIG1vZGVscyBhc3N1bWUgdGhhdCBjb21wYXJ0bWVudHMgYXJlIHdlbGwtbWl4ZWQgYW5kIHRoYXQgdGhlIHdhaXRpbmcgdGltZXMgYmV0d2VlbiBjb21wYXJ0bWVudHMgYXJlIGV4cG9uZW50aWFsbHkgZGlzdHJpYnV0ZWQuIAoKCgoKIyMjIE1vZGVsIFNldC11cApXZSBmaXJzdCBtb2RlbGVkIHRyYW5zbWlzc2lvbiBpbiBhIG1ldGFwb3B1bGF0aW9uIG9mIDcgY2FtcHMsIGFzIG9ic2VydmVkIGJ5IE1pZ2xpYW5vIGV0IGFsLiAoMjAyMyksIHdpdGggb25lIGluaXRpYWxseSBpbmZlY3RlZCBpbmRpdmlkdWFsIGZyb20gYSByYW5kb21seSBzZWxlY3RlZCBwYXRjaC4gCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBQYXRjaCBzaXplClUgPC0gbGVuZ3RoKHBhdGNoUG9wU2l6ZSkgICAgICAgICAgICAgICAgICAgICMgTnVtYmVyIG9mIHBhdGNoZXMKaW5pdGlhbF9pbmZlY3RlZCA8LSAgYXMudmVjdG9yKHJtdWx0aW5vbSgxLCAxLCByZXAoMC41LCBVKSkpICAgIyBJbml0aWFsIGluZmVjdGVkIChpbml0aWFsIGluZmVjdGVkIHBhdGNoIHJhbmRvbWx5IGdlbmVyYXRlZCkKaW5pdGlhbF9pbmZlY3RlZF9wYXRjaCA8LSB3aGljaChpbml0aWFsX2luZmVjdGVkID4gMCkKc2ltTmFtZSA8LSAiU0lSUyBtZXRhcG9wdWxhdGlvbiBtb2RlbCIgICAgICAgIyBTaW11bGF0aW9uIG5hbWUKdGYgPC0gMzY1KjMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRmluYWwgdGltZQoKIyBBZ3RhIEh1bnRlci1HYXRoZXJlciBjb250YWN0IHJhdGVzCndpdGhpbl9wb3BfY29udGFjdCA9IDEKYmV0d2Vlbl9wb3BfY29udGFjdCA9IDAuNS9VICAgICAjIG5vcm1hbGlzZWQgYnkgbnVtYmVyIG9mIHBhdGNoZXMgCgojQ3JlYXRlIHRoZSBuYW1lZCBpbml0aWFsIHN0YXRlIHZlY3RvciBmb3IgdGhlIFUtcGF0Y2ggc3lzdGVtLgoKeDBfbWV0YSA8LSB1bmxpc3QobGFwcGx5KAogIHNlcV9sZW4oVSksIAogIGZ1bmN0aW9uKGkpeyAKICAgIGMocGF0Y2hQb3BTaXplW2ldIC0gaW5pdGlhbF9pbmZlY3RlZFtpXSwgaW5pdGlhbF9pbmZlY3RlZFtpXSwgMCwgMCwgcGF0Y2hQb3BTaXplW2ldKQogIH0KKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oaSkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgaSkpKQoKCiMgRGVmaW5lIHRoZSBzdGF0ZSBjaGFuZ2UgbWF0cml4IGZvciBhIHNpbmdsZSBwYXRjaApudV9tZXRhIDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwojIE1hc3MtYWN0aW9uCmFfbWV0YSA8LQogIHVubGlzdChsYXBwbHkoCiAgICBzZXFfbGVuKFUpLAogICAgZnVuY3Rpb24ocGF0Y2gpIHsKICAgICAgaSA8LSBwYXRjaAogICAgICBwYXRjaGVzIDwtIDE6VQogICAgICAjaiA8LSBpZiAocGF0Y2ggPT0gMSkgVSBlbHNlIHBhdGNoIC0gMQogICAgICBvdGhlcl9wYXRjaGVzIDwtIHBhdGNoZXNbLWldCiAgICAgIHBhdGNoX2JldGEgPC0gYygpCiAgICAgIGZvcihrIGluICgxOihVLTEpKSl7CiAgICAgICAgcGF0Y2hfYmV0YVtrXSA9IHBhc3RlMCgiKyhiZXRhXyIsIG90aGVyX3BhdGNoZXNba10saSwgIipJIiwgb3RoZXJfcGF0Y2hlc1trXSwgIi9OIiwgb3RoZXJfcGF0Y2hlc1trXSwgIikqUyIsIGkpCiAgICAgIH0KICAgICAgYygKICAgICAgICBwYXN0ZTAoIihiZXRhXyIsIGksIGksICIqSSIsIGksIi9OIiwgaSwgIikqUyIsaSwgcGFzdGUwKHBhdGNoX2JldGEsIGNvbGxhcHNlPSIiKSksICMgSW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJzaWdtYSpFIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCZWNvbWVzIGluZmVjaW91cwogICAgICAgIHBhc3RlMCgiZ2FtbWEqSSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgUmVjb3ZlcnkgZnJvbSBpbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoIm9tZWdhKlIiLCBpKSwgICAgICAgIyBMb3NzIG9mIGltbXVuaXR5CiAgICAgICAgcGFzdGUwKCJtdSpOIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRocwogICAgICAgIHBhc3RlMCgibXUqUyIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChTKQogICAgICAgIHBhc3RlMCgibXUqRSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChFKQogICAgICAgIHBhc3RlMCgibXUqSSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChJKQogICAgICAgIHBhc3RlMCgibXUqUiIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChSKQogICAgICAgIHBhc3RlMCgiYWxwaGEqSSIsIGkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIGZyb20gaW5mZWN0aW9uCiAgICAgICAgCiAgICAgICkKICAgIH0KICApKQoKYGBgCgoKRGVmaW5lIGZ1bmN0aW9ucyBmb3IgY2FsY3VsYXRpbmcgUjAgZnJvbSBuZXh0LWdlbmVyYXRpb24gbWF0cml4CmBgYHtyfQojIENhbGN1bGF0ZSBSMCBmcm9tIE5HTQoKUjBuZ20gPC0gZnVuY3Rpb24obmV4dGdlbl9tYXRyaXgpIHsKICBlaWdlbnZhbHVlcyA9IGVpZ2VuKG5leHRnZW5fbWF0cml4LCBvbmx5LnZhbHVlcyA9IFQpCiAgUjAgPSBtYXgoYWJzKGVpZ2VudmFsdWVzJHZhbHVlcykpCiAgcmV0dXJuKFIwKQp9CgpiZXRhLm5nbSA8LSBmdW5jdGlvbihiZXRhX21hdHJpeCkgewogIGVpZ2VudmFsdWVzID0gZWlnZW4oYmV0YV9tYXRyaXgsIG9ubHkudmFsdWVzID0gVCkKICBiZXRhX25nbSA9IG1heChhYnMoZWlnZW52YWx1ZXMkdmFsdWVzKSkKICByZXR1cm4oYmV0YV9uZ20pCn0KYGBgCgoKCiMjIyBSdW4gTWV0YXBvcHVsYXRpb24gTW9kZWwKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YSA8LSBsaXN0KAogIHNpZ21hID0gMC4xNzUsICAgICAgICAgICAgICAgICAgICAgICAgICAjIEUgdG8gSSByYXRlCiAgZ2FtbWEgPSAwLjIsICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBJIHRvIFIgcmF0ZQogIG9tZWdhID0gMS8xMDAsICAgICAgICAgICAgICAgICAgICAgICAgICMgUiB0byBTIHJhdGUKICBtdSA9IGRlbW9fc3VtJEJpcnRoX3JhdGVfZGFpbHlfTWVhbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aC9kZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQogIGFscGhhID0gMS8xMDAwKSAKCiMgRGVmaW5lIHRyYW5zbWlzc2lvbiB0ZXJtcyBhbmQgcG9wdWxhdGUgbmV4dC1nZW5lcmF0aW9uIG1hdHJpeApiZXRhIDwtIDAuNgoKbmV4dGdlbl9tYXRyaXggPC0gbWF0cml4KG5yb3cgPSBVLCBuY29sID0gVSwgZGF0YSA9IDApCmJldGFfbWF0cml4IDwtIG1hdHJpeChucm93ID0gVSwgbmNvbCA9IFUsIGRhdGEgPSAwKQoKCmZvcihpIGluIDE6VSl7CiAgZm9yKGogaW4gMTpVKXsKICAgIHBhcm1zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGksaSldXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuX21hdHJpeFtpLGldID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfbWV0YSRnYW1tYSkKICAgIHBhcm1zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaSldXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl9tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc19tZXRhJGdhbW1hKQogICAgbmV4dGdlbl9tYXRyaXhbaSxqXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc19tZXRhJGdhbW1hKQogICAgcGFybXNfbWV0YVtbcGFzdGUwKCJiZXRhXyIsaixqKV1dID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICAgIG5leHRnZW5fbWF0cml4W2osal0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc19tZXRhJGdhbW1hKQogICAgYmV0YV9tYXRyaXhbaSxpXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhX21hdHJpeFtqLGldID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhX21hdHJpeFtpLGpdID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhX21hdHJpeFtqLGpdID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICB9CiAgcGFybXNfbWV0YVtbcGFzdGUwKCJOIiwgaSldXSA9IHBhdGNoUG9wU2l6ZVtpXQp9CmBgYAoKCmBgYHtyfQojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDI1KQpvdXRfbWV0YSA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIFBsb3QKcGxvdF9kYXRhX21ldGEgPC0gb3V0X21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGEgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKGFscGhhPTAuOCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDEsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUgKERheXMpIiwKICAgICAgIHk9Ik51bWJlciBvZiBJbmRpdmlkdWFscyIsCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgdGhlbWVfYncoKQpwbG90X21ldGEKCmdnc2F2ZShmaWxlbmFtZSA9ICJtZXRhX3Bsb3RfNy5wZGYiLCAKICAgICAgIHBsb3QgPSBwbG90X21ldGEsCiAgICAgICBkZXZpY2UgPSAicGRmIiwKICAgICAgIHdpZHRoID0gNywgCiAgICAgICBoZWlnaHQgPSA4LAogICAgICAgcGF0aCA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL1Bsb3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMiKQpgYGAKCmBgYHtyfQojIyBUYWJsZSBzaG93aW5nIGV4dGluY3Rpb24vdHJhbnNtaXNzaW9uIGluZm8gZm9yIGVhY2ggcGF0Y2gKCmV4dGluY3RfZGF0YV9tZXRhIDwtIG91dF9tZXRhJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgc2xpY2VfbWF4KHQpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbihzdGF0ZT09IkkiICYgY291bnQgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGU9PSJJIiAmIGNvdW50ID09IDAgfiBGKSkgJT4lCiAgZHJvcF9uYSgpICU+JQogIHNlbGVjdChwYXRjaCwgY291bnQsIHBlcnNpc3QpCmV4dGluY3RfZGF0YV9tZXRhCmBgYAoKCmBgYHtyfQpiZXRhX21ldGEgPC0gYmV0YS5uZ20oYmV0YV9tYXRyaXgpCnBhc3RlMCgiQmV0YSBmb3Igd2hvbGUgc3lzdGVtID0gIiwgYmV0YV9tZXRhKQoKClIwX21ldGEgPC0gUjBuZ20obmV4dGdlbl9tYXRyaXgpCnBhc3RlMCgiUjAgPSAiLCBSMF9tZXRhKQoKCnBhc3RlMCgiQWN0dWFsIG51bWJlciBvZiBpbmZlY3RlZHMgYXQgZW5kIG9mIHNpbSA9ICIsIHN1bShleHRpbmN0X2RhdGFfbWV0YSRjb3VudCkpCiAjIFRvdGFsIG51bWJlciBvZiBpbmZlY3RlZHMgYXQgdGhlIGVuZCBvZiBzaW0gYWNyb3NzIGFsbCBwYXRjaGVzCgpzaW1fZW5kcG9pbnRfbWV0YSA8LSBhc190aWJibGUob3V0X21ldGEkZGF0YSkgJT4lCiAgc2xpY2VfbWF4KHQpICU+JQogIGRpc3RpbmN0KCkKCgpwYXN0ZTAoIkRpZCBzaW11bGF0aW9uIHJ1biByZWFjaCBmaW5hbCBlbmRwb2ludD8iKQppZiAoc2ltX2VuZHBvaW50X21ldGEkdCA+PSB0ZikgewogIHByaW50KCJZZXMiKQp9IGVsc2UgewogIHByaW50KCJObyIpfQoKYGBgCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YSA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdChsYXBwbHkoCiAgc2VxX2xlbihVKSwgCiAgZnVuY3Rpb24oeCl7IAogICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgfQopKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCiAgCiAgb3V0XzEwMF9tZXRhIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhIDwtIG91dF8xMDBfbWV0YSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhW1tpXV0gPC0gc2ltX2RhdGFfbWV0YQp9CgpzaW1fb3V0cHV0X21ldGEgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGEpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YSA8LSBzaW1fb3V0cHV0X21ldGEgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGEKYGBgCgoKCmBgYHtyfQojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YSA8LSBzaW1fb3V0cHV0X21ldGEgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnlfbWV0YQpgYGAKCgoKIyMjIFZhcnlpbmcgd2FpbmluZyBpbW11bml0eSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KIyMjIyAwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8wIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8wJG9tZWdhIDwtIDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzAgPC0gb3V0X21ldGFfMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8wIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8wIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8wLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8wIDwtIG91dF8xMDBfbWV0YV8wJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMAp9CgpzaW1fb3V0cHV0X21ldGFfMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8wKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMCA8LSBzaW1fb3V0cHV0X21ldGFfMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8wCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8wIDwtIHNpbV9vdXRwdXRfbWV0YV8wICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMCkKc2ltX3N1bW1hcnlfbWV0YV8wCmBgYAoKCgojIyMjIDEgRGF5CmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMSA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMSRvbWVnYSA8LSAxCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8xIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzEsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xIDwtIG91dF9tZXRhXzEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzEKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzEgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8xIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMSA8LSBvdXRfMTAwX21ldGFfMSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzFbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzEKfQoKc2ltX291dHB1dF9tZXRhXzEgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzEgPC0gc2ltX291dHB1dF9tZXRhXzEgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMSA8LSBzaW1fb3V0cHV0X21ldGFfMSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxKQpzaW1fc3VtbWFyeV9tZXRhXzEKYGBgCgoKCgojIyMjIDMgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzMgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzMkb21lZ2EgPC0gMS8zCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8zIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzMsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8zIDwtIG91dF9tZXRhXzMkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMyA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzMsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzMKYGBgCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8zIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzMgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMyA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzMgPC0gb3V0XzEwMF9tZXRhXzMkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8zW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8zCn0KCnNpbV9vdXRwdXRfbWV0YV8zIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzMpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8zIDwtIHNpbV9vdXRwdXRfbWV0YV8zICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzMKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzMgPC0gc2ltX291dHB1dF9tZXRhXzMgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zKQpzaW1fc3VtbWFyeV9tZXRhXzMKYGBgCgoKCgoKCiMjIyMgNyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfNyA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfNyRvbWVnYSA8LSAxLzcKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzcgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfNywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzcgPC0gb3V0X21ldGFfNyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV83IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfNywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfNwpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzcgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfNyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV83IDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfNywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfNyA8LSBvdXRfMTAwX21ldGFfNyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzdbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzcKfQoKc2ltX291dHB1dF9tZXRhXzcgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfNykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzcgPC0gc2ltX291dHB1dF9tZXRhXzcgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfNwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfNyA8LSBzaW1fb3V0cHV0X21ldGFfNyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcpCnNpbV9zdW1tYXJ5X21ldGFfNwpgYGAKCgoKIyMjIyAxMCBEYXlzCgpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzEwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8xMCRvbWVnYSA8LSAxLzEwCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzEwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMTAgPC0gb3V0X21ldGFfMTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8xMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzEwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzEwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzEwIDwtIG91dF8xMDBfbWV0YV8xMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzEwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8xMAp9CgpzaW1fb3V0cHV0X21ldGFfMTAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8xMCA8LSBzaW1fb3V0cHV0X21ldGFfMTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMTAgPC0gc2ltX291dHB1dF9tZXRhXzEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTQpCnNpbV9zdW1tYXJ5X21ldGFfMTAKYGBgCgoKIyMjIyAyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMjAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzIwJG9tZWdhIDwtIDEvMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzIwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMjAgPC0gb3V0X21ldGFfMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8yMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzIwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzIwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzIwIDwtIG91dF8xMDBfbWV0YV8yMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzIwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8yMAp9CgpzaW1fb3V0cHV0X21ldGFfMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8yMCA8LSBzaW1fb3V0cHV0X21ldGFfMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzIwIDwtIHNpbV9vdXRwdXRfbWV0YV8yMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIwKQpzaW1fc3VtbWFyeV9tZXRhXzIwCmBgYAoKCgoKCgojIyMjIDMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8zMCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMzAkb21lZ2EgPC0gMS8zMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMzAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8zMCA8LSBvdXRfbWV0YV8zMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8zMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzMwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8zMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMzAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMzAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8zMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMzAgPC0gb3V0XzEwMF9tZXRhXzMwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMzBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzMwCn0KCnNpbV9vdXRwdXRfbWV0YV8zMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8zMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzMwIDwtIHNpbV9vdXRwdXRfbWV0YV8zMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8zMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMzAgPC0gc2ltX291dHB1dF9tZXRhXzMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zMCkKc2ltX3N1bW1hcnlfbWV0YV8zMApgYGAKCgoKIyMjIyA0MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfNDAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzQwJG9tZWdhIDwtIDEvNDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzQwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzQwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfNDAgPC0gb3V0X21ldGFfNDAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfNDAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV80MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfNDAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzQwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzQwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzQwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfNDAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzQwIDwtIG91dF8xMDBfbWV0YV80MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzQwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV80MAp9CgpzaW1fb3V0cHV0X21ldGFfNDAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfNDApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV80MCA8LSBzaW1fb3V0cHV0X21ldGFfNDAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfNDAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzQwIDwtIHNpbV9vdXRwdXRfbWV0YV80MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzQwKQpzaW1fc3VtbWFyeV9tZXRhXzQwCmBgYAoKCgoKCgoKIyMjIyA1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfNTAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzUwJG9tZWdhIDwtIDEvNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzUwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfNTAgPC0gb3V0X21ldGFfNTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV81MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfNTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzUwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzUwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzUwIDwtIG91dF8xMDBfbWV0YV81MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzUwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV81MAp9CgpzaW1fb3V0cHV0X21ldGFfNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfNTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV81MCA8LSBzaW1fb3V0cHV0X21ldGFfNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfNTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzUwIDwtIHNpbV9vdXRwdXRfbWV0YV81MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzUwKQpzaW1fc3VtbWFyeV9tZXRhXzUwCmBgYAoKCgoKCiMjIyMgNjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzYwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV82MCRvbWVnYSA8LSAxLzYwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV82MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV82MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzYwIDwtIG91dF9tZXRhXzYwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzYwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfNjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzYwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV82MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV82MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV82MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzYwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV82MCA8LSBvdXRfMTAwX21ldGFfNjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV82MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfNjAKfQoKc2ltX291dHB1dF9tZXRhXzYwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzYwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfNjAgPC0gc2ltX291dHB1dF9tZXRhXzYwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzYwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV82MCA8LSBzaW1fb3V0cHV0X21ldGFfNjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS82MCkKc2ltX3N1bW1hcnlfbWV0YV82MApgYGAKCgoKCiMjIyMgNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzcwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV83MCRvbWVnYSA8LSAxLzcwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV83MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV83MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzcwIDwtIG91dF9tZXRhXzcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfNzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV83MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV83MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV83MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV83MCA8LSBvdXRfMTAwX21ldGFfNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV83MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfNzAKfQoKc2ltX291dHB1dF9tZXRhXzcwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfNzAgPC0gc2ltX291dHB1dF9tZXRhXzcwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV83MCA8LSBzaW1fb3V0cHV0X21ldGFfNzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83MCkKc2ltX3N1bW1hcnlfbWV0YV83MApgYGAKCgojIyMjIDgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV84MCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfODAkb21lZ2EgPC0gMS84MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfODAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV84MCA8LSBvdXRfbWV0YV84MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV84MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzgwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV84MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfODAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfODAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV84MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfODAgPC0gb3V0XzEwMF9tZXRhXzgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfODBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzgwCn0KCnNpbV9vdXRwdXRfbWV0YV84MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV84MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzgwIDwtIHNpbV9vdXRwdXRfbWV0YV84MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV84MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfODAgPC0gc2ltX291dHB1dF9tZXRhXzgwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvODApCnNpbV9zdW1tYXJ5X21ldGFfODAKYGBgCgoKCiMjIyMgOTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzkwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV85MCRvbWVnYSA8LSAxLzkwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV85MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV85MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzkwIDwtIG91dF9tZXRhXzkwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzkwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfOTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzkwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV85MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV85MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV85MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzkwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV85MCA8LSBvdXRfMTAwX21ldGFfOTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV85MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfOTAKfQoKc2ltX291dHB1dF9tZXRhXzkwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzkwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfOTAgPC0gc2ltX291dHB1dF9tZXRhXzkwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzkwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV85MCA8LSBzaW1fb3V0cHV0X21ldGFfOTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS85MCkKc2ltX3N1bW1hcnlfbWV0YV85MApgYGAKCgoKCgoKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8xODAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjApCm91dF9tZXRhXzE4MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8xODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xODAgPC0gb3V0X21ldGFfMTgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzE4MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzE4MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMTgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8xODAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMTgwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzE4MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzE4MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMTgwIDwtIG91dF8xMDBfbWV0YV8xODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8xODBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzE4MAp9CgpzaW1fb3V0cHV0X21ldGFfMTgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzE4MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzE4MCA8LSBzaW1fb3V0cHV0X21ldGFfMTgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzE4MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMTgwIDwtIHNpbV9vdXRwdXRfbWV0YV8xODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xODApCnNpbV9zdW1tYXJ5X21ldGFfMTgwCmBgYAoKIyMjIyAxMTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzExMCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMTEwJG9tZWdhIDwtIDEvMTEwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8xMTAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMTEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMTEwIDwtIG91dF9tZXRhXzExMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8xMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8xMTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzExMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMTEwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzExMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8xMTAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8xMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzExMCA8LSBvdXRfMTAwX21ldGFfMTEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMTEwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8xMTAKfQoKc2ltX291dHB1dF9tZXRhXzExMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8xMTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8xMTAgPC0gc2ltX291dHB1dF9tZXRhXzExMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8xMTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzExMCA8LSBzaW1fb3V0cHV0X21ldGFfMTEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTEwKQpzaW1fc3VtbWFyeV9tZXRhXzExMApgYGAKCiMjIyMgMTIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8xMjAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzEyMCRvbWVnYSA8LSAxLzEyMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMTIwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzEyMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzEyMCA8LSBvdXRfbWV0YV8xMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMTIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMTIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8xMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzEyMCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8xMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMTIwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMTIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8xMjAgPC0gb3V0XzEwMF9tZXRhXzEyMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzEyMFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMTIwCn0KCnNpbV9vdXRwdXRfbWV0YV8xMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMTIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMTIwIDwtIHNpbV9vdXRwdXRfbWV0YV8xMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMTIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xMjAgPC0gc2ltX291dHB1dF9tZXRhXzEyMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEyMCkKc2ltX3N1bW1hcnlfbWV0YV8xMjAKYGBgCgojIyMjIDEzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMTMwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8xMzAkb21lZ2EgPC0gMS8xMzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzEzMCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8xMzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xMzAgPC0gb3V0X21ldGFfMTMwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzEzMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzEzMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMTMwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8xMzAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMTMwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzEzMCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzEzMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMTMwIDwtIG91dF8xMDBfbWV0YV8xMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8xMzBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzEzMAp9CgpzaW1fb3V0cHV0X21ldGFfMTMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzEzMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzEzMCA8LSBzaW1fb3V0cHV0X21ldGFfMTMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzEzMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMTMwIDwtIHNpbV9vdXRwdXRfbWV0YV8xMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMzApCnNpbV9zdW1tYXJ5X21ldGFfMTMwCmBgYAoKCgoKCgoKCgoKCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMTUwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8xNTAkb21lZ2EgPC0gMS8xNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzE1MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8xNTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xNTAgPC0gb3V0X21ldGFfMTUwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzE1MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzE1MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMTUwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8xNTAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMTUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzE1MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzE1MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMTUwIDwtIG91dF8xMDBfbWV0YV8xNTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8xNTBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzE1MAp9CgpzaW1fb3V0cHV0X21ldGFfMTUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzE1MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzE1MCA8LSBzaW1fb3V0cHV0X21ldGFfMTUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzE1MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMTUwIDwtIHNpbV9vdXRwdXRfbWV0YV8xNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNTApCnNpbV9zdW1tYXJ5X21ldGFfMTUwCmBgYAoKCiMjIyMgMjIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8yMjAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzIyMCRvbWVnYSA8LSAxLzIyMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMjIwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzIyMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzIyMCA8LSBvdXRfbWV0YV8yMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMjIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMjIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8yMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzIyMCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8yMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMjIwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMjIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8yMjAgPC0gb3V0XzEwMF9tZXRhXzIyMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzIyMFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMjIwCn0KCnNpbV9vdXRwdXRfbWV0YV8yMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMjIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMjIwIDwtIHNpbV9vdXRwdXRfbWV0YV8yMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMjIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8yMjAgPC0gc2ltX291dHB1dF9tZXRhXzIyMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIyMCkKc2ltX3N1bW1hcnlfbWV0YV8yMjAKYGBgCgoKCgojIyMjIDI3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMjcwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8yNzAkb21lZ2EgPC0gMS8yNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzI3MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8yNzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8yNzAgPC0gb3V0X21ldGFfMjcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzI3MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzI3MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMjcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8yNzAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMjcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzI3MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzI3MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMjcwIDwtIG91dF8xMDBfbWV0YV8yNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8yNzBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzI3MAp9CgpzaW1fb3V0cHV0X21ldGFfMjcwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzI3MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzI3MCA8LSBzaW1fb3V0cHV0X21ldGFfMjcwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzI3MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMjcwIDwtIHNpbV9vdXRwdXRfbWV0YV8yNzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yNzApCnNpbV9zdW1tYXJ5X21ldGFfMjcwCmBgYAoKIyMjIyAzNjUgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzM2NSA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMzY1JG9tZWdhIDwtIDEvMzY1CgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8zNjUgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMzY1LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMzY1IDwtIG91dF9tZXRhXzM2NSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8zNjUgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8zNjUsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzM2NQpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMzY1IDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzM2NSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8zNjUgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8zNjUsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzM2NSA8LSBvdXRfMTAwX21ldGFfMzY1JGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMzY1W1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8zNjUKfQoKc2ltX291dHB1dF9tZXRhXzM2NSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8zNjUpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8zNjUgPC0gc2ltX291dHB1dF9tZXRhXzM2NSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8zNjUKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzM2NSA8LSBzaW1fb3V0cHV0X21ldGFfMzY1ICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzY1KQpzaW1fc3VtbWFyeV9tZXRhXzM2NQpgYGAKClNpbmdsZQoKCgoKCiMjIyMgUmVzdWx0cwpgYGB7cn0Kd2FuaW5nX3Jlc3VsdHNfNyA8LSBzaW1fc3VtbWFyeV9tZXRhICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzMpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzcpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8yMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzQwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV81MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfNjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzcwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV84MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfOTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzEwMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMTEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8xMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzEzMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMTUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8yMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzI3MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMzY1KSAlPiUKICBtdXRhdGUoaW1tdW5pdHlfZHVyYXRpb24gPSAxL29tZWdhKSAlPiUKICBhcnJhbmdlKGltbXVuaXR5X2R1cmF0aW9uKSAlPiUKICBtdXRhdGUobW9kZWwgPSAibWV0YSIsCiAgICAgICAgIHBhdGNoZXMgPSA3KQoKd3JpdGVfY3N2KHdhbmluZ19yZXN1bHRzXzcsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL1Jlc3VsdHMvd2FuaW5nX3Jlc3VsdHNfNy5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfNwoKYGBgCgpgYGB7cn0KZ2dwbG90KHdhbmluZ19yZXN1bHRzXzcsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgc3VtX3BlcnNpc3QpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX2J3KCkKYGBgCgoKCgojIyAzLVBhdGNoIE1ldGFwb3B1bGF0aW9uIE1vZGVsIAoKVGhlIHNhbWUgbWV0YXBvcHVsYXRpb24gU0VJUlMgbW9kZWwgd2FzIHRoZW4gdXNlZCB0byBtb2RlbCB0aGUgZHluYW1pY3Mgb2YgcGVyc2lzdGVuY2UgaW4gYSAzLXBhdGNoIHN5c3RlbSBhbmQgdW5kZXJzdGFuZCB0aGUgZWZmZWN0IG9mIHdhbmluZyBpbW11bml0eS4KCiMjI1NldC11cAoKYGBge3J9CiMgRGVmaW5lIFBhcmFtZW50ZXJzCnBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBQYXRjaCBzaXplClUgPC0gbGVuZ3RoKHBhdGNoUG9wU2l6ZV8zKSAgICAgICAgICAgICAgICAgICAgIyBOdW1iZXIgb2YgcGF0Y2hlcwppbml0aWFsX2luZmVjdGVkIDwtICBhcy52ZWN0b3Iocm11bHRpbm9tKDEsIDEsIHJlcCgwLjUsIFUpKSkgICAjIEluaXRpYWwgaW5mZWN0ZWQgKGluaXRpYWwgaW5mZWN0ZWQgcGF0Y2ggcmFuZG9tbHkgZ2VuZXJhdGVkKQppbml0aWFsX2luZmVjdGVkX3BhdGNoIDwtIHdoaWNoKGluaXRpYWxfaW5mZWN0ZWQgPiAwKQpzaW1OYW1lIDwtICJTSVJTIG1ldGFwb3B1bGF0aW9uIG1vZGVsIiAgICAgICAjIFNpbXVsYXRpb24gbmFtZQp0ZiA8LSAzNjUqMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBGaW5hbCB0aW1lCgojIEFndGEgSHVudGVyLUdhdGhlcmVyIGNvbnRhY3QgcmF0ZXMKd2l0aGluX3BvcF9jb250YWN0ID0gMQpiZXR3ZWVuX3BvcF9jb250YWN0ID0gMC41L1UgICAgICMgbm9ybWFsaXNlZCBieSBudW1iZXIgb2YgcGF0Y2hlcyAKCiNDcmVhdGUgdGhlIG5hbWVkIGluaXRpYWwgc3RhdGUgdmVjdG9yIGZvciB0aGUgVS1wYXRjaCBzeXN0ZW0uCgp4MF8zX21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbihpKXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8zW2ldIC0gaW5pdGlhbF9pbmZlY3RlZFtpXSwgaW5pdGlhbF9pbmZlY3RlZFtpXSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbaV0pCiAgfQopKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKGkpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIGkpKSkKCgojIERlZmluZSB0aGUgc3RhdGUgY2hhbmdlIG1hdHJpeCBmb3IgYSBzaW5nbGUgcGF0Y2gKbnVfM19tZXRhIDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwojIE1hc3MtYWN0aW9uCmFfM19tZXRhIDwtCiAgdW5saXN0KGxhcHBseSgKICAgIHNlcV9sZW4oVSksCiAgICBmdW5jdGlvbihwYXRjaCkgewogICAgICBpIDwtIHBhdGNoCiAgICAgIHBhdGNoZXMgPC0gMTpVCiAgICAgICNqIDwtIGlmIChwYXRjaCA9PSAxKSBVIGVsc2UgcGF0Y2ggLSAxCiAgICAgIG90aGVyX3BhdGNoZXMgPC0gcGF0Y2hlc1staV0KICAgICAgcGF0Y2hfYmV0YSA8LSBjKCkKICAgICAgZm9yKGsgaW4gKDE6KFUtMSkpKXsKICAgICAgICBwYXRjaF9iZXRhW2tdID0gcGFzdGUwKCIrKGJldGFfIiwgb3RoZXJfcGF0Y2hlc1trXSxpLCAiKkkiLCBvdGhlcl9wYXRjaGVzW2tdLCAiL04iLCBvdGhlcl9wYXRjaGVzW2tdLCAiKSpTIiwgaSkKICAgICAgfQogICAgICBjKAogICAgICAgIHBhc3RlMCgiKGJldGFfIiwgaSwgaSwgIipJIiwgaSwiL04iLCBpLCAiKSpTIixpLCBwYXN0ZTAocGF0Y2hfYmV0YSwgY29sbGFwc2U9IiIpKSwgIyBJbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoInNpZ21hKkUiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJlY29tZXMgaW5mZWNpb3VzCiAgICAgICAgcGFzdGUwKCJnYW1tYSpJIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBSZWNvdmVyeSBmcm9tIGluZmVjdGlvbgogICAgICAgIHBhc3RlMCgib21lZ2EqUiIsIGkpLCAgICAgICAjIExvc3Mgb2YgaW1tdW5pdHkKICAgICAgICBwYXN0ZTAoIm11Kk4iLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGhzCiAgICAgICAgcGFzdGUwKCJtdSpTIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFMpCiAgICAgICAgcGFzdGUwKCJtdSpFIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEUpCiAgICAgICAgcGFzdGUwKCJtdSpJIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEkpCiAgICAgICAgcGFzdGUwKCJtdSpSIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFIpCiAgICAgICAgcGFzdGUwKCJhbHBoYSpJIiwgaSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgZnJvbSBpbmZlY3Rpb24KICAgICAgICAKICAgICAgKQogICAgfQogICkpCgpgYGAKCgoKIyMjIFJ1biBNZXRhcG9wdWxhdGlvbiBNb2RlbApgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGEgPC0gbGlzdCgKICBzaWdtYSA9IDAuMTc1LCAgICAgICAgICAgICAgICAgICAgICAgICAgIyBFIHRvIEkgcmF0ZQogIGdhbW1hID0gMC4yLCAgICAgICAgICAgICAgICAgICAgICAgICAgICMgSSB0byBSIHJhdGUKICBvbWVnYSA9IDEvMTAwLCAgICAgICAgICAgICAgICAgICAgICAgICAjIFIgdG8gUyByYXRlCiAgbXUgPSBkZW1vX3N1bSRCaXJ0aF9yYXRlX2RhaWx5X01lYW4sICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGgvZGVhdGggcmF0ZSBwZXIgcGVyc29uIHBlciBkYXkKICBhbHBoYSA9IDEvMTAwMCkgCgojIERlZmluZSB0cmFuc21pc3Npb24gdGVybXMgYW5kIHBvcHVsYXRlIG5leHQtZ2VuZXJhdGlvbiBtYXRyaXgKYmV0YSA8LSAwLjYKCm5leHRnZW5fM19tYXRyaXggPC0gbWF0cml4KG5yb3cgPSBVLCBuY29sID0gVSwgZGF0YSA9IDApCmJldGFfM19tYXRyaXggPC0gbWF0cml4KG5yb3cgPSBVLCBuY29sID0gVSwgZGF0YSA9IDApCgoKZm9yKGkgaW4gMTpVKXsKICBmb3IoaiBpbiAxOlUpewogICAgcGFybXNfM19tZXRhW1twYXN0ZTAoImJldGFfIixpLGkpXV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl8zX21hdHJpeFtpLGldID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfM19tZXRhJGdhbW1hKQogICAgcGFybXNfM19tZXRhW1twYXN0ZTAoImJldGFfIixqLGkpXV0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEKICAgIG5leHRnZW5fM19tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18zX21ldGEkZ2FtbWEpCiAgICBuZXh0Z2VuXzNfbWF0cml4W2ksal0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfM19tZXRhJGdhbW1hKQogICAgcGFybXNfM19tZXRhW1twYXN0ZTAoImJldGFfIixqLGopXV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl8zX21hdHJpeFtqLGpdID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfM19tZXRhJGdhbW1hKQogICAgYmV0YV8zX21hdHJpeFtpLGldID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICAgIGJldGFfM19tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV8zX21hdHJpeFtpLGpdID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhXzNfbWF0cml4W2osal0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogIH0KICBwYXJtc18zX21ldGFbW3Bhc3RlMCgiTiIsIGkpXV0gPSBwYXRjaFBvcFNpemVfM1tpXQp9CmBgYAoKCmBgYHtyfQojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDI1KQpvdXRfM19tZXRhIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGEsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBQbG90CnBsb3RfZGF0YV8zX21ldGEgPC0gb3V0XzNfbWV0YSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKGFscGhhPTAuOCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDEsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUgKERheXMpIiwKICAgICAgIHk9Ik51bWJlciBvZiBJbmRpdmlkdWFscyIsCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YQoKZ2dzYXZlKGZpbGVuYW1lID0gIm1ldGFfcGxvdF8zLnBkZiIsIAogICAgICAgcGxvdCA9IHBsb3RfM19tZXRhLAogICAgICAgZGV2aWNlID0gInBkZiIsCiAgICAgICB3aWR0aCA9IDcsIAogICAgICAgaGVpZ2h0ID0gOCwKICAgICAgIHBhdGggPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9QbG90cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzIikKYGBgCgpgYGB7cn0KIyMgVGFibGUgc2hvd2luZyBleHRpbmN0aW9uL3RyYW5zbWlzc2lvbiBpbmZvIGZvciBlYWNoIHBhdGNoCgpleHRpbmN0X2RhdGFfM19tZXRhIDwtIG91dF8zX21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHN0YXRlPT0iSSIgJiBjb3VudCA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZT09IkkiICYgY291bnQgPT0gMCB+IEYpKSAlPiUKICBkcm9wX25hKCkgJT4lCiAgc2VsZWN0KHBhdGNoLCBjb3VudCwgcGVyc2lzdCkKZXh0aW5jdF9kYXRhXzNfbWV0YQpgYGAKCgpgYGB7cn0KYmV0YV8zX21ldGEgPC0gYmV0YS5uZ20oYmV0YV8zX21hdHJpeCkKcGFzdGUwKCJCZXRhIGZvciB3aG9sZSBzeXN0ZW0gPSAiLCBiZXRhXzNfbWV0YSkKCgpSMF8zX21ldGEgPC0gUjBuZ20obmV4dGdlbl8zX21hdHJpeCkKcGFzdGUwKCJSMCA9ICIsIFIwXzNfbWV0YSkKCgpwYXN0ZTAoIkFjdHVhbCBudW1iZXIgb2YgaW5mZWN0ZWRzIGF0IGVuZCBvZiBzaW0gPSAiLCBzdW0oZXh0aW5jdF9kYXRhXzNfbWV0YSRjb3VudCkpCiAjIFRvdGFsIG51bWJlciBvZiBpbmZlY3RlZHMgYXQgdGhlIGVuZCBvZiBzaW0gYWNyb3NzIGFsbCBwYXRjaGVzCgpzaW1fZW5kcG9pbnRfM19tZXRhIDwtIGFzX3RpYmJsZShvdXRfM19tZXRhJGRhdGEpICU+JQogIHNsaWNlX21heCh0KSAlPiUKICBkaXN0aW5jdCgpCgoKcGFzdGUwKCJEaWQgc2ltdWxhdGlvbiBydW4gcmVhY2ggZmluYWwgZW5kcG9pbnQ/IikKaWYgKHNpbV9lbmRwb2ludF8zX21ldGEkdCA+PSB0ZikgewogIHByaW50KCJZZXMiKQp9IGVsc2UgewogIHByaW50KCJObyIpfQoKYGBgCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGEgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbih4KXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgfQopKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKICAKICBvdXRfMTAwXzNfbWV0YSA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGEgPC0gb3V0XzEwMF8zX21ldGEkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhCn0KCnNpbV9vdXRwdXRfM19tZXRhIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGEpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhIDwtIHNpbV9vdXRwdXRfM19tZXRhICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGEKYGBgCgoKCmBgYHtyfQojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhIDwtIHNpbV9vdXRwdXRfM19tZXRhICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMDApCnNpbV9zdW1tYXJ5XzNfbWV0YQpgYGAKCiMjIyBWYXJ5aW5nIHdhaW5pbmcgaW1tdW5pdHkgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9CiMjIyMgMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8wIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMCRvbWVnYSA8LSAwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8wLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8wIDwtIG91dF8zX21ldGFfMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8wIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8wIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8wLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzAgPC0gb3V0XzEwMF8zX21ldGFfMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8wCn0KCnNpbV9vdXRwdXRfM19tZXRhXzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8wKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8wIDwtIHNpbV9vdXRwdXRfM19tZXRhXzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8wCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzAgPC0gc2ltX291dHB1dF8zX21ldGFfMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDApCnNpbV9zdW1tYXJ5XzNfbWV0YV8wCmBgYAoKCgojIyMjIDEgRGF5CmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMSRvbWVnYSA8LSAxCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzEgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xIDwtIG91dF8zX21ldGFfMSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzEgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMQpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8xIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8xIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzEgPC0gb3V0XzEwMF8zX21ldGFfMSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMVtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xCn0KCnNpbV9vdXRwdXRfM19tZXRhXzEgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8xKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xIDwtIHNpbV9vdXRwdXRfM19tZXRhXzEgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8xCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzEgPC0gc2ltX291dHB1dF8zX21ldGFfMSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxKQpzaW1fc3VtbWFyeV8zX21ldGFfMQpgYGAKCgoKCiMjIyMgMyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8zIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMyRvbWVnYSA8LSAxLzMKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMyA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzMsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzMgPC0gb3V0XzNfbWV0YV8zJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMyA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfMywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8zCmBgYAoKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8zIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8zIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8zLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzMgPC0gb3V0XzEwMF8zX21ldGFfMyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfM1tbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8zCn0KCnNpbV9vdXRwdXRfM19tZXRhXzMgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8zKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8zIDwtIHNpbV9vdXRwdXRfM19tZXRhXzMgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8zCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzMgPC0gc2ltX291dHB1dF8zX21ldGFfMyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMpCnNpbV9zdW1tYXJ5XzNfbWV0YV8zCmBgYAoKCgoKCgojIyMjIDcgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfNyA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzckb21lZ2EgPC0gMS83CgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzcgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV83LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV83IDwtIG91dF8zX21ldGFfNyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzcgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzcsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfNwpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfNyA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzcgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfNyA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfNywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV83IDwtIG91dF8xMDBfM19tZXRhXzckZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzdbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfNwp9CgpzaW1fb3V0cHV0XzNfbWV0YV83IDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfNykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfNyA8LSBzaW1fb3V0cHV0XzNfbWV0YV83ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfNwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV83IDwtIHNpbV9vdXRwdXRfM19tZXRhXzcgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83KQpzaW1fc3VtbWFyeV8zX21ldGFfNwpgYGAKCgoKIyMjIyAxMCBEYXlzCgpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMTAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xMCRvbWVnYSA8LSAxLzEwCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMTAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMTAgPC0gb3V0XzNfbWV0YV8xMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzEwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8xMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8xMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzEwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8xMCA8LSBvdXRfMTAwXzNfbWV0YV8xMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMTBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMTAKfQoKc2ltX291dHB1dF8zX21ldGFfMTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8xMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMTAgPC0gc2ltX291dHB1dF8zX21ldGFfMTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8xMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE0KQpzaW1fc3VtbWFyeV8zX21ldGFfMTAKYGBgCgoKIyMjIyAyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8yMCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzIwJG9tZWdhIDwtIDEvMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMjAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8yMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMjAgPC0gb3V0XzNfbWV0YV8yMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8yMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8yMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8yMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzIwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8yMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8yMCA8LSBvdXRfMTAwXzNfbWV0YV8yMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMjBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMjAKfQoKc2ltX291dHB1dF8zX21ldGFfMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8yMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMjAgPC0gc2ltX291dHB1dF8zX21ldGFfMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8yMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8yMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8yMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIwKQpzaW1fc3VtbWFyeV8zX21ldGFfMjAKYGBgCgoKCgoKCiMjIyMgMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMzAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8zMCRvbWVnYSA8LSAxLzMwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzMwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzMwIDwtIG91dF8zX21ldGFfMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8zMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMzAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV8zMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8zMCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfMzAgPC0gb3V0XzEwMF8zX21ldGFfMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzMwW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzMwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzMwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfMzAgPC0gc2ltX291dHB1dF8zX21ldGFfMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMwKQpzaW1fc3VtbWFyeV8zX21ldGFfMzAKYGBgCgoKCiMjIyMgNDAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfNDAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV80MCRvbWVnYSA8LSAxLzQwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzQwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfNDAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzQwIDwtIG91dF8zX21ldGFfNDAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV80MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfNDAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfNDAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfNDAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV80MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV80MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfNDAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfNDAgPC0gb3V0XzEwMF8zX21ldGFfNDAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzQwW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzQwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzQwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfNDApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzQwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzQwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfNDAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfNDAgPC0gc2ltX291dHB1dF8zX21ldGFfNDAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS80MCkKc2ltX3N1bW1hcnlfM19tZXRhXzQwCmBgYAoKCgoKCgoKIyMjIyA1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV81MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzUwJG9tZWdhIDwtIDEvNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfNTAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV81MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfNTAgPC0gb3V0XzNfbWV0YV81MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzUwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV81MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV81MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV81MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzUwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV81MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV81MCA8LSBvdXRfMTAwXzNfbWV0YV81MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfNTBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfNTAKfQoKc2ltX291dHB1dF8zX21ldGFfNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV81MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfNTAgPC0gc2ltX291dHB1dF8zX21ldGFfNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV81MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV81MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV81MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzUwKQpzaW1fc3VtbWFyeV8zX21ldGFfNTAKYGBgCgoKCgoKIyMjIyA2MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV82MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzYwJG9tZWdhIDwtIDEvNjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfNjAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV82MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfNjAgPC0gb3V0XzNfbWV0YV82MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzYwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV82MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV82MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV82MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzYwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzYwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV82MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV82MCA8LSBvdXRfMTAwXzNfbWV0YV82MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfNjBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfNjAKfQoKc2ltX291dHB1dF8zX21ldGFfNjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV82MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfNjAgPC0gc2ltX291dHB1dF8zX21ldGFfNjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV82MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV82MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV82MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzYwKQpzaW1fc3VtbWFyeV8zX21ldGFfNjAKYGBgCgoKCgojIyMjIDcwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzcwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfNzAkb21lZ2EgPC0gMS83MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV83MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzcwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV83MCA8LSBvdXRfM19tZXRhXzcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfNzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzcwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzcwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfNzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfNzAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzcwIDwtIG91dF8xMDBfM19tZXRhXzcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV83MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV83MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV83MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV83MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV83MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzcwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzcwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNzApCnNpbV9zdW1tYXJ5XzNfbWV0YV83MApgYGAKCgojIyMjIDgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzgwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfODAkb21lZ2EgPC0gMS84MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV84MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV84MCA8LSBvdXRfM19tZXRhXzgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfODAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzgwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzgwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfODAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzgwIDwtIG91dF8xMDBfM19tZXRhXzgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV84MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV84MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV84MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV84MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV84MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzgwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzgwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvODApCnNpbV9zdW1tYXJ5XzNfbWV0YV84MApgYGAKCgoKIyMjIyA5MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV85MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzkwJG9tZWdhIDwtIDEvOTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfOTAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV85MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfOTAgPC0gb3V0XzNfbWV0YV85MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzkwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV85MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV85MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV85MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzkwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzkwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV85MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV85MCA8LSBvdXRfMTAwXzNfbWV0YV85MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfOTBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfOTAKfQoKc2ltX291dHB1dF8zX21ldGFfOTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV85MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfOTAgPC0gc2ltX291dHB1dF8zX21ldGFfOTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV85MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV85MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV85MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzkwKQpzaW1fc3VtbWFyeV8zX21ldGFfOTAKYGBgCgoKCgoKCgojIyMjIDE4MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xODAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xODAkb21lZ2EgPC0gMS8xODAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDIwKQpvdXRfM19tZXRhXzE4MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzE4MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMTgwIDwtIG91dF8zX21ldGFfMTgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMTgwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8xODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMTgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzE4MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzE4MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8xODAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzE4MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8xODAgPC0gb3V0XzEwMF8zX21ldGFfMTgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xODBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMTgwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzE4MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzE4MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMTgwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzE4MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzE4MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8xODAgPC0gc2ltX291dHB1dF8zX21ldGFfMTgwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTgwKQpzaW1fc3VtbWFyeV8zX21ldGFfMTgwCmBgYAoKIyMjIyAxMTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMTEwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMTEwJG9tZWdhIDwtIDEvMTEwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzExMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzExMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMTEwIDwtIG91dF8zX21ldGFfMTEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMTEwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8xMTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMTEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzExMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzExMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8xMTAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzExMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8xMTAgPC0gb3V0XzEwMF8zX21ldGFfMTEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xMTBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMTEwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzExMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzExMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMTEwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzExMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzExMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8xMTAgPC0gc2ltX291dHB1dF8zX21ldGFfMTEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTEwKQpzaW1fc3VtbWFyeV8zX21ldGFfMTEwCmBgYAoKIyMjIyAxMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMTIwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMTIwJG9tZWdhIDwtIDEvMTIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzEyMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzEyMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMTIwIDwtIG91dF8zX21ldGFfMTIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMTIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8xMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMTIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzEyMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzEyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8xMjAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzEyMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8xMjAgPC0gb3V0XzEwMF8zX21ldGFfMTIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xMjBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMTIwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzEyMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzEyMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMTIwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzEyMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzEyMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8xMjAgPC0gc2ltX291dHB1dF8zX21ldGFfMTIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTIwKQpzaW1fc3VtbWFyeV8zX21ldGFfMTIwCmBgYAoKIyMjIyAxMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMTMwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMTMwJG9tZWdhIDwtIDEvMTMwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzEzMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzEzMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMTMwIDwtIG91dF8zX21ldGFfMTMwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMTMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8xMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMTMwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzEzMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzEzMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8xMzAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzEzMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8xMzAgPC0gb3V0XzEwMF8zX21ldGFfMTMwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xMzBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMTMwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzEzMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzEzMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMTMwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzEzMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzEzMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8xMzAgPC0gc2ltX291dHB1dF8zX21ldGFfMTMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTMwKQpzaW1fc3VtbWFyeV8zX21ldGFfMTMwCmBgYAoKCgoKCgoKCgoKCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xNTAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xNTAkb21lZ2EgPC0gMS8xNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMTUwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMTUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xNTAgPC0gb3V0XzNfbWV0YV8xNTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8xNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzE1MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xNTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMTUwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzE1MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMTUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzE1MCA8LSBvdXRfMTAwXzNfbWV0YV8xNTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzE1MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xNTAKfQoKc2ltX291dHB1dF8zX21ldGFfMTUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMTUwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xNTAgPC0gc2ltX291dHB1dF8zX21ldGFfMTUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMTUwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzE1MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNTApCnNpbV9zdW1tYXJ5XzNfbWV0YV8xNTAKYGBgCgoKIyMjIyAyMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMjIwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMjIwJG9tZWdhIDwtIDEvMjIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzIyMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzIyMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMjIwIDwtIG91dF8zX21ldGFfMjIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMjIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8yMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMjIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzIyMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzIyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8yMjAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzIyMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8yMjAgPC0gb3V0XzEwMF8zX21ldGFfMjIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8yMjBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMjIwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzIyMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzIyMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMjIwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzIyMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzIyMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8yMjAgPC0gc2ltX291dHB1dF8zX21ldGFfMjIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjIwKQpzaW1fc3VtbWFyeV8zX21ldGFfMjIwCmBgYAoKCgoKIyMjIyAyNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMjcwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMjcwJG9tZWdhIDwtIDEvMjcwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzI3MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzI3MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMjcwIDwtIG91dF8zX21ldGFfMjcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMjcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8yNzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMjcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzI3MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzI3MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8yNzAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzI3MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8yNzAgPC0gb3V0XzEwMF8zX21ldGFfMjcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8yNzBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMjcwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzI3MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzI3MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMjcwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzI3MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzI3MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8yNzAgPC0gc2ltX291dHB1dF8zX21ldGFfMjcwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjcwKQpzaW1fc3VtbWFyeV8zX21ldGFfMjcwCmBgYAoKIyMjIyAzNjUgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMzY1IDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMzY1JG9tZWdhIDwtIDEvMzY1CgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzM2NSA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzM2NSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMzY1IDwtIG91dF8zX21ldGFfMzY1JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMzY1IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8zNjUsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMzY1CmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzM2NSA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzM2NSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8zNjUgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzM2NSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8zNjUgPC0gb3V0XzEwMF8zX21ldGFfMzY1JGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8zNjVbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMzY1Cn0KCnNpbV9vdXRwdXRfM19tZXRhXzM2NSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzM2NSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMzY1IDwtIHNpbV9vdXRwdXRfM19tZXRhXzM2NSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzM2NQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8zNjUgPC0gc2ltX291dHB1dF8zX21ldGFfMzY1ICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzY1KQpzaW1fc3VtbWFyeV8zX21ldGFfMzY1CmBgYAoKCgoKIyMjIyBSZXN1bHRzCmBgYHtyfQp3YW5pbmdfcmVzdWx0c18zIDwtIHNpbV9zdW1tYXJ5XzNfbWV0YSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzMpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfNykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8xMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8yMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8zMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV80MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV81MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV82MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV83MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV84MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV85MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8xODApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMTEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzEyMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8xMzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMTUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzIyMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8yNzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMzY1KSAlPiUKICBtdXRhdGUoaW1tdW5pdHlfZHVyYXRpb24gPSAxL29tZWdhKSAlPiUKICBhcnJhbmdlKGltbXVuaXR5X2R1cmF0aW9uKSAlPiUKICBtdXRhdGUobW9kZWwgPSAibWV0YSIsCiAgICAgICAgIHBhdGNoZXMgPSAzKQoKd3JpdGVfY3N2KHdhbmluZ19yZXN1bHRzXzMsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL1Jlc3VsdHMvd2FuaW5nX3Jlc3VsdHNfMy5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfMwoKYGBgCgpgYGB7cn0KZ2dwbG90KHdhbmluZ19yZXN1bHRzXzMsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgc3VtX3BlcnNpc3QpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX2J3KCkKYGBgCgoKCgoKCiMjIDE0IE1ldGFwb3B1bGF0aW9uIE1vZGVsIAoKVGhlIHNhbWUgbWV0YXBvcHVsYXRpb24gU0VJUlMgbW9kZWwgd2FzIHRoZW4gdXNlZCB0byBtb2RlbCB0aGUgZHluYW1pY3Mgb2YgcGVyc2lzdGVuY2UgaW4gYSAxNC1wYXRjaCBzeXN0ZW0gYW5kIHVuZGVyc3RhbmQgdGhlIGVmZmVjdCBvZiB3YW5pbmcgaW1tdW5pdHkuCgoKIyMjU2V0LXVwCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKcGF0Y2hQb3BTaXplXzE0IDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgUGF0Y2ggc2l6ZQpVIDwtIGxlbmd0aChwYXRjaFBvcFNpemVfMTQpICAgICAgICAgICAgICAgICAgICAjIE51bWJlciBvZiBwYXRjaGVzCmluaXRpYWxfaW5mZWN0ZWQgPC0gIGFzLnZlY3RvcihybXVsdGlub20oMSwgMSwgcmVwKDAuNSwgVSkpKSAgICMgSW5pdGlhbCBpbmZlY3RlZCAoaW5pdGlhbCBpbmZlY3RlZCBwYXRjaCByYW5kb21seSBnZW5lcmF0ZWQpCmluaXRpYWxfaW5mZWN0ZWRfcGF0Y2ggPC0gd2hpY2goaW5pdGlhbF9pbmZlY3RlZCA+IDApCnNpbU5hbWUgPC0gIlNJUlMgbWV0YXBvcHVsYXRpb24gbW9kZWwiICAgICAgICMgU2ltdWxhdGlvbiBuYW1lCnRmIDwtIDM2NSozICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEZpbmFsIHRpbWUKCiMgQWd0YSBIdW50ZXItR2F0aGVyZXIgY29udGFjdCByYXRlcwp3aXRoaW5fcG9wX2NvbnRhY3QgPSAxCmJldHdlZW5fcG9wX2NvbnRhY3QgPSAwLjUvVSAgICAgIyBub3JtYWxpc2VkIGJ5IG51bWJlciBvZiBwYXRjaGVzIAoKI0NyZWF0ZSB0aGUgbmFtZWQgaW5pdGlhbCBzdGF0ZSB2ZWN0b3IgZm9yIHRoZSBVLXBhdGNoIHN5c3RlbS4KCngwXzE0X21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbihpKXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8xNFtpXSAtIGluaXRpYWxfaW5mZWN0ZWRbaV0sIGluaXRpYWxfaW5mZWN0ZWRbaV0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8xNFtpXSkKICB9CikpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKGkpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIGkpKSkKCgojIERlZmluZSB0aGUgc3RhdGUgY2hhbmdlIG1hdHJpeCBmb3IgYSBzaW5nbGUgcGF0Y2gKbnVfMTRfbWV0YSA8LSBtYXRyaXgoYyggLTEsICAwLCAgMCwgKzEsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsICMgUwogICAgICAgICAgICAgICAgICAgICArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICAwLCAgMCwgIyBFCiAgICAgICAgICAgICAgICAgICAgICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsIC0xLCAjIEkKICAgICAgICAgICAgICAgICAgICAgIDAsICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICMgUiAKICAgICAgICAgICAgICAgICAgICAgIDAsICAwLCAgMCwgIDAsICsxLCAtMSAsLTEsIC0xLCAtMSwgLTEpLCAjIE4KICAgICAgICAgICAgIG5yb3c9NSxieXJvdz1UUlVFKQoKIyBEZWZpbmUgcHJvcGVuc2l0eSBmdW5jdGlvbnMKIyBNYXNzLWFjdGlvbgphXzE0X21ldGEgPC0KICB1bmxpc3QobGFwcGx5KAogICAgc2VxX2xlbihVKSwKICAgIGZ1bmN0aW9uKHBhdGNoKSB7CiAgICAgIGkgPC0gcGF0Y2gKICAgICAgcGF0Y2hlcyA8LSAxOlUKICAgICAgI2ogPC0gaWYgKHBhdGNoID09IDEpIFUgZWxzZSBwYXRjaCAtIDEKICAgICAgb3RoZXJfcGF0Y2hlcyA8LSBwYXRjaGVzWy1pXQogICAgICBwYXRjaF9iZXRhIDwtIGMoKQogICAgICBmb3IoayBpbiAoMTooVS0xKSkpewogICAgICAgIHBhdGNoX2JldGFba10gPSBwYXN0ZTAoIisoYmV0YV8iLCBvdGhlcl9wYXRjaGVzW2tdLGksICIqSSIsIG90aGVyX3BhdGNoZXNba10sICIvTiIsIG90aGVyX3BhdGNoZXNba10sICIpKlMiLCBpKQogICAgICB9CiAgICAgIGMoCiAgICAgICAgcGFzdGUwKCIoYmV0YV8iLCBpLCBpLCAiKkkiLCBpLCIvTiIsIGksICIpKlMiLGksIHBhc3RlMChwYXRjaF9iZXRhLCBjb2xsYXBzZT0iIikpLCAjIEluZmVjdGlvbgogICAgICAgIHBhc3RlMCgic2lnbWEqRSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmVjb21lcyBpbmZlY2lvdXMKICAgICAgICBwYXN0ZTAoImdhbW1hKkkiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFJlY292ZXJ5IGZyb20gaW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJvbWVnYSpSIiwgaSksICAgICAgICMgTG9zcyBvZiBpbW11bml0eQogICAgICAgIHBhc3RlMCgibXUqTiIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aHMKICAgICAgICBwYXN0ZTAoIm11KlMiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUykKICAgICAgICBwYXN0ZTAoIm11KkUiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoRSkKICAgICAgICBwYXN0ZTAoIm11KkkiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoSSkKICAgICAgICBwYXN0ZTAoIm11KlIiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUikKICAgICAgICBwYXN0ZTAoImFscGhhKkkiLCBpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyBmcm9tIGluZmVjdGlvbgogICAgICAgIAogICAgICApCiAgICB9CiAgKSkKCmBgYAoKCgojIyMgUnVuIE1ldGFwb3B1bGF0aW9uIE1vZGVsCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGEgPC0gbGlzdCgKICBzaWdtYSA9IDAuMTc1LCAgICAgICAgICAgICAgICAgICAgICAgICAgIyBFIHRvIEkgcmF0ZQogIGdhbW1hID0gMC4yLCAgICAgICAgICAgICAgICAgICAgICAgICAgICMgSSB0byBSIHJhdGUKICBvbWVnYSA9IDEvMTAwLCAgICAgICAgICAgICAgICAgICAgICAgICAjIFIgdG8gUyByYXRlCiAgbXUgPSBkZW1vX3N1bSRCaXJ0aF9yYXRlX2RhaWx5X01lYW4sICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGgvZGVhdGggcmF0ZSBwZXIgcGVyc29uIHBlciBkYXkKICBhbHBoYSA9IDEvMTAwMCkgCgojIERlZmluZSB0cmFuc21pc3Npb24gdGVybXMgYW5kIHBvcHVsYXRlIG5leHQtZ2VuZXJhdGlvbiBtYXRyaXgKYmV0YSA8LSAwLjYKCm5leHRnZW5fMTRfbWF0cml4IDwtIG1hdHJpeChucm93ID0gVSwgbmNvbCA9IFUsIGRhdGEgPSAwKQpiZXRhXzE0X21hdHJpeCA8LSBtYXRyaXgobnJvdyA9IFUsIG5jb2wgPSBVLCBkYXRhID0gMCkKCgpmb3IoaSBpbiAxOlUpewogIGZvcihqIGluIDE6VSl7CiAgICBwYXJtc18xNF9tZXRhW1twYXN0ZTAoImJldGFfIixpLGkpXV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl8xNF9tYXRyaXhbaSxpXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhKigxL3Bhcm1zXzE0X21ldGEkZ2FtbWEpCiAgICBwYXJtc18xNF9tZXRhW1twYXN0ZTAoImJldGFfIixqLGkpXV0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEKICAgIG5leHRnZW5fMTRfbWF0cml4W2osaV0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfMTRfbWV0YSRnYW1tYSkKICAgIG5leHRnZW5fMTRfbWF0cml4W2ksal0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfMTRfbWV0YSRnYW1tYSkKICAgIHBhcm1zXzE0X21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaildXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuXzE0X21hdHJpeFtqLGpdID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfMTRfbWV0YSRnYW1tYSkKICAgIGJldGFfMTRfbWF0cml4W2ksaV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV8xNF9tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV8xNF9tYXRyaXhbaSxqXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV8xNF9tYXRyaXhbaixqXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgfQogIHBhcm1zXzE0X21ldGFbW3Bhc3RlMCgiTiIsIGkpXV0gPSBwYXRjaFBvcFNpemVfMTRbaV0KfQpgYGAKCgpgYGB7cn0KIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyNSkKb3V0XzE0X21ldGEgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGEsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBQbG90CnBsb3RfZGF0YV8xNF9tZXRhIDwtIG91dF8xNF9tZXRhJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZShhbHBoYT0wLjgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIChEYXlzKSIsCiAgICAgICB5PSJOdW1iZXIgb2YgSW5kaXZpZHVhbHMiLAogICAgICAgY29sb3VyPSJTdGF0ZSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhCgpnZ3NhdmUoZmlsZW5hbWUgPSAibWV0YV8xNF9wbG90LnBkZiIsIAogICAgICAgcGxvdCA9IHBsb3RfMTRfbWV0YSwKICAgICAgIGRldmljZSA9ICJwZGYiLAogICAgICAgd2lkdGggPSA3LCAKICAgICAgIGhlaWdodCA9IDgsCiAgICAgICBwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvUGxvdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscyIpCmBgYAoKYGBge3J9CiMjIFRhYmxlIHNob3dpbmcgZXh0aW5jdGlvbi90cmFuc21pc3Npb24gaW5mbyBmb3IgZWFjaCBwYXRjaAoKZXh0aW5jdF9kYXRhXzE0X21ldGEgPC0gb3V0XzE0X21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHN0YXRlPT0iSSIgJiBjb3VudCA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZT09IkkiICYgY291bnQgPT0gMCB+IEYpKSAlPiUKICBkcm9wX25hKCkgJT4lCiAgc2VsZWN0KHBhdGNoLCBjb3VudCwgcGVyc2lzdCkKZXh0aW5jdF9kYXRhXzE0X21ldGEKYGBgCgoKYGBge3J9CmJldGFfMTRfbWV0YSA8LSBiZXRhLm5nbShiZXRhXzE0X21hdHJpeCkKcGFzdGUwKCJCZXRhIGZvciB3aG9sZSBzeXN0ZW0gPSAiLCBiZXRhXzE0X21ldGEpCgoKUjBfMTRfbWV0YSA8LSBSMG5nbShuZXh0Z2VuXzE0X21hdHJpeCkKcGFzdGUwKCJSMCA9ICIsIFIwXzE0X21ldGEpCgoKcGFzdGUwKCJBY3R1YWwgbnVtYmVyIG9mIGluZmVjdGVkcyBhdCBlbmQgb2Ygc2ltID0gIiwgc3VtKGV4dGluY3RfZGF0YV8xNF9tZXRhJGNvdW50KSkKICMgVG90YWwgbnVtYmVyIG9mIGluZmVjdGVkcyBhdCB0aGUgZW5kIG9mIHNpbSBhY3Jvc3MgYWxsIHBhdGNoZXMKCnNpbV9lbmRwb2ludF8xNF9tZXRhIDwtIGFzX3RpYmJsZShvdXRfMTRfbWV0YSRkYXRhKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKQoKCnBhc3RlMCgiRGlkIHNpbXVsYXRpb24gcnVuIHJlYWNoIGZpbmFsIGVuZHBvaW50PyIpCmlmIChzaW1fZW5kcG9pbnRfMTRfbWV0YSR0ID49IHRmKSB7CiAgcHJpbnQoIlllcyIpCn0gZWxzZSB7CiAgcHJpbnQoIk5vIil9CgpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzE0IDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdChsYXBwbHkoCiAgc2VxX2xlbihVKSwgCiAgZnVuY3Rpb24oeCl7IAogICAgYyhwYXRjaFBvcFNpemVfMTRbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfMTRbeF0pCiAgfQopKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCiAgCiAgb3V0XzEwMF8xNF9tZXRhIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhIDwtIG91dF8xMDBfMTRfbWV0YSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YQp9CgpzaW1fb3V0cHV0XzE0X21ldGEgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGEpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YSA8LSBzaW1fb3V0cHV0XzE0X21ldGEgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGEKYGBgCgoKCmBgYHtyfQojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YSA8LSBzaW1fb3V0cHV0XzE0X21ldGEgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnlfMTRfbWV0YQpgYGAKCiMjIyBWYXJ5aW5nIHdhaW5pbmcgaW1tdW5pdHkgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9CiMjIyMgMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMCRvbWVnYSA8LSAwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8wIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8wIDwtIG91dF8xNF9tZXRhXzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzAgPC0gb3V0XzEwMF8xNF9tZXRhXzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8wW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8wCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8wIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8wIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8wICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzAKYGBgCgoKIyMjIyAxMCBEYXlzCgpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzEwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8xMCRvbWVnYSA8LSAxLzEwCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzEwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMTAgPC0gb3V0XzE0X21ldGFfMTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8xMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzEwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8xMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzEwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8xMCA8LSBvdXRfMTAwXzE0X21ldGFfMTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8xMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMTAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzEwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzEwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzEwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzEwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzEwCmBgYAoKCiMjIyMgMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzIwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8yMCRvbWVnYSA8LSAxLzIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8yMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8yMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzIwIDwtIG91dF8xNF9tZXRhXzIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8yMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8yMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMjAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8yMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMjAgPC0gb3V0XzEwMF8xNF9tZXRhXzIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMjBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzIwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8yMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8yMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzIwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8yMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8yMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMjAKYGBgCgoKCgoKCiMjIyMgMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzMwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8zMCRvbWVnYSA8LSAxLzMwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8zMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8zMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzMwIDwtIG91dF8xNF9tZXRhXzMwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzMwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8zMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8zMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMzAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8zMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMzAgPC0gb3V0XzEwMF8xNF9tZXRhXzMwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMzBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzMwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8zMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8zMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzMwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8zMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8zMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8zMApgYGAKCgoKIyMjIyA0MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfNDAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzQwJG9tZWdhIDwtIDEvNDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzQwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzQwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfNDAgPC0gb3V0XzE0X21ldGFfNDAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfNDAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV80MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfNDAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzQwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzQwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV80MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzQwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV80MCA8LSBvdXRfMTAwXzE0X21ldGFfNDAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV80MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfNDAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzQwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzQwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfNDAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzQwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzQwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV80MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfNDAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS80MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV80MApgYGAKCgoKCgoKCiMjIyMgNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzUwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV81MCRvbWVnYSA8LSAxLzUwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV81MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV81MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzUwIDwtIG91dF8xNF9tZXRhXzUwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzUwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfNTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzUwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV81MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV81MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfNTAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV81MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfNTAgPC0gb3V0XzEwMF8xNF9tZXRhXzUwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfNTBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzUwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV81MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV81MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzUwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV81MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV81MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfNTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzUwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNTApCnNpbV9zdW1tYXJ5XzE0X21ldGFfNTAKYGBgCgoKCgoKIyMjIyA2MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfNjAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzYwJG9tZWdhIDwtIDEvNjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzYwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzYwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfNjAgPC0gb3V0XzE0X21ldGFfNjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfNjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV82MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfNjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzYwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzYwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV82MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzYwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV82MCA8LSBvdXRfMTAwXzE0X21ldGFfNjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV82MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfNjAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzYwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzYwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfNjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzYwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzYwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV82MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfNjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS82MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV82MApgYGAKCgoKCiMjIyMgNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzcwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV83MCRvbWVnYSA8LSAxLzcwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV83MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV83MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzcwIDwtIG91dF8xNF9tZXRhXzcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfNzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV83MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV83MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfNzAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV83MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfNzAgPC0gb3V0XzEwMF8xNF9tZXRhXzcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfNzBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzcwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV83MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV83MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzcwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV83MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV83MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfNzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzcwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNzApCnNpbV9zdW1tYXJ5XzE0X21ldGFfNzAKYGBgCgoKIyMjIyA4MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfODAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzgwJG9tZWdhIDwtIDEvODAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzgwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfODAgPC0gb3V0XzE0X21ldGFfODAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfODAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV84MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfODAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzgwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzgwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV84MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV84MCA8LSBvdXRfMTAwXzE0X21ldGFfODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV84MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfODAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfODAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV84MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV84MApgYGAKCgoKIyMjIyA5MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfOTAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzkwJG9tZWdhIDwtIDEvOTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzkwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzkwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfOTAgPC0gb3V0XzE0X21ldGFfOTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfOTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV85MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfOTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzkwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzkwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV85MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzkwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV85MCA8LSBvdXRfMTAwXzE0X21ldGFfOTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV85MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfOTAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzkwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzkwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfOTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzkwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzkwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV85MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfOTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS85MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV85MApgYGAKCgoKCgoKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8xODAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjApCm91dF8xNF9tZXRhXzE4MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8xODAgPC0gb3V0XzE0X21ldGFfMTgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzE4MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzE4MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMTgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8xODAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMTgwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8xODAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzE4MCA8LSBvdXRfMTAwXzE0X21ldGFfMTgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMTgwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8xODAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzE4MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8xODApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8xODAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzE4MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8xODAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzE4MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTgwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTgwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzE4MApgYGAKCiMjIyMgMTEwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8xMTAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzExMCRvbWVnYSA8LSAxLzExMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMTEwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzExMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzExMCA8LSBvdXRfMTRfbWV0YV8xMTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMTEwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMTEwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8xMTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzExMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8xMTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzExMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzExMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMTEwIDwtIG91dF8xMDBfMTRfbWV0YV8xMTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8xMTBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzExMAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMTEwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzExMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzExMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTEwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzExMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMTEwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMTApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMTEwCmBgYAoKIyMjIyAxMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzEyMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMTIwJG9tZWdhIDwtIDEvMTIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8xMjAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMTIwIDwtIG91dF8xNF9tZXRhXzEyMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8xMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8xMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzEyMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMTIwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzEyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMTIwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8xMjAgPC0gb3V0XzEwMF8xNF9tZXRhXzEyMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzEyMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMTIwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8xMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMTIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMTIwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMTIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8xMjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzEyMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEyMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8xMjAKYGBgCgojIyMjIDEzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMTMwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8xMzAkb21lZ2EgPC0gMS8xMzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzEzMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xMzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8xMzAgPC0gb3V0XzE0X21ldGFfMTMwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzEzMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzEzMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMTMwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8xMzAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMTMwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8xMzAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzEzMCA8LSBvdXRfMTAwXzE0X21ldGFfMTMwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMTMwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8xMzAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzEzMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8xMzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8xMzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzEzMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8xMzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzEzMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTMwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzEzMApgYGAKCgoKCgoKCgoKCgoKIyMjIyAxNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzE1MCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMTUwJG9tZWdhIDwtIDEvMTUwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8xNTAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMTUwIDwtIG91dF8xNF9tZXRhXzE1MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8xNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8xNTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzE1MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMTUwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzE1MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMTUwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8xNTAgPC0gb3V0XzEwMF8xNF9tZXRhXzE1MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzE1MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMTUwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8xNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMTUwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMTUwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMTUwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8xNTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzE1MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE1MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8xNTAKYGBgCgoKIyMjIyAyMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzIyMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMjIwJG9tZWdhIDwtIDEvMjIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8yMjAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMjIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMjIwIDwtIG91dF8xNF9tZXRhXzIyMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8yMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8yMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzIyMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMjIwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzIyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMjIwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMjIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8yMjAgPC0gb3V0XzEwMF8xNF9tZXRhXzIyMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzIyMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMjIwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8yMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMjIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMjIwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8yMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMjIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8yMjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzIyMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIyMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8yMjAKYGBgCgoKCgojIyMjIDI3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMjcwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8yNzAkb21lZ2EgPC0gMS8yNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzI3MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8yNzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8yNzAgPC0gb3V0XzE0X21ldGFfMjcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzI3MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzI3MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMjcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8yNzAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMjcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8yNzAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8yNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzI3MCA8LSBvdXRfMTAwXzE0X21ldGFfMjcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMjcwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8yNzAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzI3MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8yNzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8yNzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzI3MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8yNzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzI3MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMjcwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjcwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzI3MApgYGAKCiMjIyMgMzY1IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8zNjUgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzM2NSRvbWVnYSA8LSAxLzM2NQoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMzY1IDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzM2NSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzM2NSA8LSBvdXRfMTRfbWV0YV8zNjUkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMzY1IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMzY1LCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8zNjUKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzM2NSA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8zNjUgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzM2NSA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzM2NSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMzY1IDwtIG91dF8xMDBfMTRfbWV0YV8zNjUkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8zNjVbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzM2NQp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMzY1IDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzM2NSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzM2NSA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMzY1ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzM2NQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMzY1IDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8zNjUgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5XzE0X21ldGFfMzY1CmBgYAoKCgoKCiMjIyMgUmVzdWx0cwpgYGB7cn0Kd2FuaW5nX3Jlc3VsdHNfMTQgPC0gc2ltX3N1bW1hcnlfMTRfbWV0YSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8xMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzMwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV80MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfNTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzYwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV83MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfODApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzkwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8xODApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzExMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMTIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8xMzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzE1MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMjIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8yNzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzM2NSkgJT4lCiAgbXV0YXRlKGltbXVuaXR5X2R1cmF0aW9uID0gMS9vbWVnYSkgJT4lCiAgYXJyYW5nZShpbW11bml0eV9kdXJhdGlvbikgJT4lCiAgbXV0YXRlKG1vZGVsID0gIm1ldGEiLAogICAgICAgICBwYXRjaGVzID0gMTQpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHNfMTQsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL1Jlc3VsdHMvd2FuaW5nX3Jlc3VsdHNfMTQuY3N2IikKCndhbmluZ19yZXN1bHRzXzE0CgpgYGAKCmBgYHtyfQpnZ3Bsb3Qod2FuaW5nX3Jlc3VsdHNfMTQsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgc3VtX3BlcnNpc3QpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX2J3KCkKYGBgCgoKIyMgQ29tYmluZWQgUmVzdWx0cwoKUmVzdWx0cyBmcm9tIHNpbmFsZSBhbmQgbWV0YXBvcHVsYXRpb24gbW9kZWxzIHdlcmUgY29taW5lZCBpbnRvIG9uZSBkYXRhIGZyYW1lIGFuZCB2aXN1YWxpc2VkLiAKCmBgYHtyfQpjb21iaW5lZF93YW5pbmcgPC0gd2FuaW5nX3Jlc3VsdHMgJT4lCiAgYmluZF9yb3dzKHdhbmluZ19yZXN1bHRzX3NpbmdsZSkgJT4lCiAgYmluZF9yb3dzKHdhbmluZ19yZXN1bHRzXzcpICU+JQogIGJpbmRfcm93cyh3YW5pbmdfcmVzdWx0c18zKSAlPiUKICBiaW5kX3Jvd3Mod2FuaW5nX3Jlc3VsdHNfMTQpCgpoZWFkKGNvbWJpbmVkX3dhbmluZykKCgojd3JpdGVfY3N2KGNvbWJpbmVkX3dhbmluZywgZmlsZSA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUmVzdWx0cy9jb21iaW5lZF93YW5pbmdfcmVzdWx0cy5jc3YiKQoKYGBgCgoKYGBge3J9CnBhbCA8LSB3ZXNfcGFsZXR0ZSg0LCBuYW1lID0gIlppc3NvdTEiLCB0eXBlID0gImNvbnRpbnVvdXMiKQoKY29tYmluZWRfcGxvdCA8LSBnZ3Bsb3QoY29tYmluZWRfd2FuaW5nLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIHN1bV9wZXJzaXN0LCBjb2xvdXIgPSBhcy5mYWN0b3IocGF0Y2hlcykpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC43LCBzaXplPTEpKwogIGdlb21fcG9pbnQoYWxwaGE9MC41LCBzaXplPTIpKwogIGdlb21fc2VnbWVudCh4ID0gLUluZiwgeSA9IDUwLCB4ZW5kID0gMTQxLjUsIHllbmQgPSA1MCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA1LCB5ID0gNTAsIHhlbmQgPSA1LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA0Mi41LCB5ID0gNTAsIHhlbmQgPSA0Mi41LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA5MS41LCB5ID0gNTAsIHhlbmQgPSA5MS41LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSAxNDEuNSwgeSA9IDUwLCB4ZW5kID0gMTQxLjUsIHllbmQgPSAtSW5mLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvdXIgPSAiZ3JleSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMTApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAzNjAsIDUwKSkgKwogIGxhYnMoeCA9ICJEdXJhdGlvbiBvZiBpbW11bml0eSAoZGF5cykiLAogICAgICAgeSA9ICJQcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzICglKSIsIAogICAgICAgY29sb3VyID0gIk5vLiBQYXRjaGVzIikrCiAgc2NhbGVfY29sb3JfZGlzY3JldGUodHlwZSA9IHBhbCwKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCIxIiwgIjMiLCAiNyIsICIxNCIpKSsKICB0aGVtZV9idygpCgpjb21iaW5lZF9wbG90CgpnZ3NhdmUoZmlsZW5hbWUgPSAiY29tYmluZWRfcGxvdF9wYXRjaGVzLnBkZiIsIHBsb3QgPSBjb21iaW5lZF9wbG90LCBkZXZpY2UgPSAicGRmIiwgd2lkdGggPSA3LCBoZWlnaHQgPSA1LCBwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscy9QbG90cyIpCmBgYAoKYGBge3J9CmdncGxvdChjb21iaW5lZF93YW5pbmcsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgbWVhbl9wZXJjZW50X2luZmVjdGVkLCBjb2xvdXIgPSBhcy5mYWN0b3IocGF0Y2hlcykpKSsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkgKwogIGxhYnMoeCA9ICJEdXJhdGlvbiBvZiBpbW11bml0eSIsCiAgICAgICB5ID0gIlByb3BvcnRpb24gaW5mZWN0ZWQgYXQgZW5kcG9pbnQgKCUpIiwgCiAgICAgICBjb2xvdXIgPSAiUGF0Y2hlcyIpKwogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKHR5cGUgPSBwYWwsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMSIsICIzIiwgIjciLCAiMTQiKSkrCiAgdGhlbWVfYncoKQpgYGAKCgojIyAzLVBhdGNoIFNpbmdsZSBQb3B1bGF0aW9uCgo8PDw8PDw8IEhFQUQKMyBtb3JlIHNpbmdsZSBwb3B1bGF0aW9uIG1vZGVscyB3ZXJlIHJhbiB0byB1bmRlcnN0YW5kIGlmIHRoZSBpbmNyZWFzZWQgcHJvYmFiaWxpdHkgb2YgcGVyc2lzdGVuY2Ugd2FzIGJlaW5nIGNhdXNlZCBieSBpbmNyZWFzaW5nIHBvcHVsYXRpb24gc2l6ZS4gVGhlc2UgbW9kZWxzIHdlcmUgdGhlIHNhbWUgYXMgdGhlIGluaXRpYWwgc2luZ2xlIHBvdWxhdGlvbiBtb2RlbCwgYnV0IGluc3RlYWQgJE4kIHdhcyBpbmNyZWFzZWQgdG8gdGhlIHN1bSBvZiAzLCA3LCBvciAxNCByYW5kb21seSBzYW1wbGVkIGNhbXBzaXplcyBmcm9tIER5YmxlIGV0IGFsLiAoMjAyMSkuCgo9PT09PT09Cj4+Pj4+Pj4gNjcyNzI4MDI4ZjE4YjJmYzIyNDMyMjk5M2QyNDVjOWE2ZWU3MWJmMQojIyMgTW9kZWwgU2V0LXVwCgpNb2RlbCB3YXMgc2V0IHVwIHdpdGggYSBzaW5nbGUgcmFuZG9tbHkgc2VsZWN0ZWQgY2FtcCBzaXplIHdpdGggYSBzaW5nbGUgaW5mZWN0ZWQgaW5kaXZpZHVhbCBhbmQgcGFyYW1ldGVycyBmb3IgcGF0aG9nZW4gWC4gCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKPDw8PDw8PCBIRUFECk5fYSA8LSAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgVG90YWwgUG9wdWxhdGlvbiBzaXplIG9mIHRocmVlIGNhbXBzCj09PT09PT0KTl9hIDwtICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBQb3B1bGF0aW9uIHNpemUKPj4+Pj4+PiA2NzI3MjgwMjhmMThiMmZjMjI0MzIyOTkzZDI0NWM5YTZlZTcxYmYxCmluaXRpYWxfaW5mZWN0ZWQgPC0gIDEgICAgIyBJbml0aWFsIGluZmVjdGVkCnNpbU5hbWUgPC0gIlNFSVJTIG1vZGVsIiAgICAgICAjIFNpbXVsYXRpb24gbmFtZQp0ZiA8LSAzNjUqMwoKI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtcyA8LSBsaXN0KAogIGJldGEgPSAwLjYsCiAgc2lnbWEgPSAwLjE3NSwgICAgICAgICAgICAgICAgICAgICAgICAgICMgRSB0byBJIHJhdGUKICBnYW1tYSA9IDAuMiwgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEkgdG8gUiByYXRlCiAgb21lZ2EgPSAxLzEwMCwgICAgICAgICAgICAgICAgICAgICAgICAgIyBSIHRvIFMgcmF0ZQogIG11ID0gZGVtb19zdW0kQmlydGhfcmF0ZV9kYWlseV9NZWFuLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRoL2RlYXRoIHJhdGUgcGVyIHBlcnNvbiBwZXIgZGF5CiAgYWxwaGEgPSAxLzEwMDApIAoKI0NyZWF0ZSB0aGUgbmFtZWQgaW5pdGlhbCBzdGF0ZSB2ZWN0b3IgZm9yIHRoZSBVLXBhdGNoIHN5c3RlbS4KCngwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgpuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgojIERlZmluZSB0aGUgc3RhdGUgY2hhbmdlIG1hdHJpeCBmb3IgYSBzaW5nbGUgcGF0Y2gKbnUgPC0gbWF0cml4KGMoIC0xLCAgMCwgIDAsICsxLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAjIFMKICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwphIDwtYygKICAgICAgICBwYXN0ZTAoIihiZXRhKkkvTikqUyIpLCAjIEluZmVjdGlvbgogICAgICAgIHBhc3RlMCgic2lnbWEqRSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmVjb21lcyBpbmZlY2lvdXMKICAgICAgICBwYXN0ZTAoImdhbW1hKkkiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFJlY292ZXJ5IGZyb20gaW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJvbWVnYSpSIiksICAgICAgICMgTG9zcyBvZiBpbW11bml0eQogICAgICAgIHBhc3RlMCgibXUqTiIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aHMKICAgICAgICBwYXN0ZTAoIm11KlMiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUykKICAgICAgICBwYXN0ZTAoIm11KkUiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoRSkKICAgICAgICBwYXN0ZTAoIm11KkkiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoSSkKICAgICAgICBwYXN0ZTAoIm11KlIiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUikKICAgICAgICBwYXN0ZTAoImFscGhhKkkiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyBmcm9tIGluZmVjdGlvbgogICAgICAgIAogICAgICApCgpgYGAKCgojIyMgUnVuIFNpbmdsZSBQb3B1bGF0aW9uIE1vZGVsCmBgYHtyfQoKRUlFX3NpbmdsZSA8LSBFSUUoUjBfc2luZ2xlLCBwYXJtcykgIyBwcm9wb3J0aW9uIG9mIGV4cGVjdGVkIGluZmVjdGVkcyBhdCBlcXVpbGlicml1bQpFSUVfc2luZ2xlCgpleHBleHRlZF9pbmZlY3RlZHMgPC0gRUlFX3NpbmdsZSpOX2EgIyBudW1iZXIgb2YgZXhwZWN0ZWQgaW5mZWN0ZWRzIGF0IGVxdWlsaWJyaXVtCmV4cGV4dGVkX2luZmVjdGVkcwoKc3FydChOX2EpICMgbWFnbml0dWRlIG9mIG9zY2lsbGF0aW9ucyAKYGBgCgpgYGB7cn0KIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyMSkKb3V0X2EgPC0gc3NhKAogIHgwID0geDBfYSwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXMsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikgCgoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9hIDwtIG91dF9hJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpzaW5nbGVfcGxvdF9hIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX2EsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZShhbHBoYT0wLjgpKwogIGxhYnMoeD0iVGltZSAoRGF5cykiLAogICAgICAgeT0iTnVtYmVyIG9mIEluZGl2aWR1YWxzIiwgCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZXhwZXh0ZWRfaW5mZWN0ZWRzLCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArCiAgdGhlbWVfYncoKQoKc2luZ2xlX3Bsb3RfYQpgYGAKCmBgYHtyfQpwbG90X2RhdGFfYSAlPiUKICBmaWx0ZXIoc3RhdGUgPT0gIkkiKSAlPiUKICBzbGljZV9tYXgoY291bnQpCmBgYApPdXRicmVhayBwZWFrZWQgYXQgZGF5IDMyIHdpdGggMzEgaW5mZWN0ZWQgaW5kaXZpZHVhbHMuCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfYSA8LSBsaXN0KCkKc2ltX2xpc3RfYSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgc2V0LnNlZWQoaSkKICBvdXRfMTAwX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtcywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX2EgPC0gb3V0XzEwMF9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9hW1tpXV0gPC0gc2ltX2RhdGFfYQp9CgpzaW1fb3V0cHV0X2EgPC0gYmluZF9yb3dzKHNpbV9saXN0X2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfYSA8LSBzaW1fb3V0cHV0X2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpoZWFkKHNpbV9vdXRwdXRfYSkKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9hIDwtIHNpbV9vdXRwdXRfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnlfYQpgYGAKCiMjIyBWYXJ5aW5nIHdhaW5pbmcgaW1tdW5pdHkgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9CldhbmluZyBpbW11bml0eSB3YXMgdGhvdWdodCB0byBwbGF5IGFuIGltcG9ydGFudCByb2xlIGluIHRoZSBwZXJzaXN0ZW5jZSBvZiBwYXRob2dlbiBYIHNvIHdlIGluY3JlbWVudGFsbHkgaW5jcmVhc2VkIHRoZSBkdXJhdGlvbiBvZiBpbW11bml0eSAoYnkgZGVjcmVhc2luZyAkXG9tZWdhJCkgYW5kIGNhbGN1bGF0ZWQgdGhlIHByb2JhYmlsaXR5IG9mIHBlcnNpc3RlbmNlIGFmdGVyIDMgeWVhcnMgaW4gMTAwMCBzdG9jaGFzdGljIHNpbXVsYXRpb25zLiBEdXJhdGlvbiBvZiBpbW11bml0eSB3YXMgaW5jcmVhc2VkIGZyb20gMSBkYXkgdG8gYSB5ZWFyLgoKIyMjIyAwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMCA8LSBwYXJtcwpwYXJtc18wJG9tZWdhIDwtIDAKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzBfYSA8LSBsaXN0KCkKc2ltX2xpc3RfMF9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMF9hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzBfYSA8LSBvdXRfMTAwXzBfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMF9hW1tpXV0gPC0gc2ltX2RhdGFfMF9hCn0KCnNpbV9vdXRwdXRfMF9hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8wX2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMF9hIDwtIHNpbV9vdXRwdXRfMF9hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8wX2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8wX2EgPC0gc2ltX291dHB1dF8wX2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMCkKc2ltX3N1bW1hcnlfMF9hCmBgYAoKCgoKIyMjIyAxIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMSA8LSBwYXJtcwpwYXJtc18xJG9tZWdhIDwtIDEKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzFfYSA8LSBsaXN0KCkKc2ltX2xpc3RfMV9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMV9hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzFfYSA8LSBvdXRfMTAwXzFfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMV9hW1tpXV0gPC0gc2ltX2RhdGFfMV9hCn0KCnNpbV9vdXRwdXRfMV9hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xX2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMV9hIDwtIHNpbV9vdXRwdXRfMV9hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xX2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xX2EgPC0gc2ltX291dHB1dF8xX2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMSkKc2ltX3N1bW1hcnlfMV9hCmBgYAoKCgoKCiMjIyMgMyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzMgPC0gcGFybXMKcGFybXNfMyRvbWVnYSA8LSAxLzMKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfYSA8LSBsaXN0KCkKc2ltX2xpc3RfM19hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfM19hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfYSA8LSBvdXRfMTAwXzNfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19hW1tpXV0gPC0gc2ltX2RhdGFfM19hCn0KCnNpbV9vdXRwdXRfM19hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19hIDwtIHNpbV9vdXRwdXRfM19hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX2EgPC0gc2ltX291dHB1dF8zX2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zKQpzaW1fc3VtbWFyeV8zX2EKYGBgCgojIyMjIDcgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc183IDwtIHBhcm1zCnBhcm1zXzckb21lZ2EgPC0gMS83CgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF83X2EgPC0gbGlzdCgpCnNpbV9saXN0XzdfYSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYSA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMpKSAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfN19hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzdfYSA8LSBvdXRfMTAwXzdfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfN19hW1tpXV0gPC0gc2ltX2RhdGFfN19hCn0KCnNpbV9vdXRwdXRfN19hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF83X2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfN19hIDwtIHNpbV9vdXRwdXRfN19hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF83X2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV83X2EgPC0gc2ltX291dHB1dF83X2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83KQpzaW1fc3VtbWFyeV83X2EKYGBgCgojIyMjIDEwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTAgPC0gcGFybXMKcGFybXNfMTAkb21lZ2EgPC0gMS8xMAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzEwX2EgPC0gbGlzdCgpCnNpbV9saXN0XzEwX2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xMF9hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xMF9hIDwtIG91dF8xMDBfMTBfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTBfYVtbaV1dIDwtIHNpbV9kYXRhXzEwX2EKfQoKc2ltX291dHB1dF8xMF9hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xMF9hKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzEwX2EgPC0gc2ltX291dHB1dF8xMF9hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xMF9hCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTBfYSA8LSBzaW1fb3V0cHV0XzEwX2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMCkKc2ltX3N1bW1hcnlfMTBfYQpgYGAKCiMjIyMgMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18yMCA8LSBwYXJtcwpwYXJtc18yMCRvbWVnYSA8LSAxLzIwCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8yMF9hIDwtIGxpc3QoKQpzaW1fbGlzdF8yMF9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMjBfYSA8LSBzc2EoCiAgICB4MCA9IHgwX2EsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMjBfYSA8LSBvdXRfMTAwXzIwX2EkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzIwX2FbW2ldXSA8LSBzaW1fZGF0YV8yMF9hCn0KCnNpbV9vdXRwdXRfMjBfYSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMjBfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8yMF9hIDwtIHNpbV9vdXRwdXRfMjBfYSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMjBfYQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzIwX2EgPC0gc2ltX291dHB1dF8yMF9hICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjApCnNpbV9zdW1tYXJ5XzIwX2EKYGBgCgojIyMjIDMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMzAgPC0gcGFybXMKcGFybXNfMzAkb21lZ2EgPC0gMS8zMAoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMzBfYSA8LSBsaXN0KCkKc2ltX2xpc3RfMzBfYSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYSA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYSA8LSBjKE5fYSAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYSkKCiAgbmFtZXMoeDBfYSkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzMwX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18zMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzMwX2EgPC0gb3V0XzEwMF8zMF9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zMF9hW1tpXV0gPC0gc2ltX2RhdGFfMzBfYQp9CgpzaW1fb3V0cHV0XzMwX2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzMwX2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMzBfYSA8LSBzaW1fb3V0cHV0XzMwX2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzMwX2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zMF9hIDwtIHNpbV9vdXRwdXRfMzBfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMwKQpzaW1fc3VtbWFyeV8zMF9hCmBgYAoKIyMjIyA0MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzQwIDwtIHBhcm1zCnBhcm1zXzQwJG9tZWdhIDwtIDEvNDAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF80MF9hIDwtIGxpc3QoKQpzaW1fbGlzdF80MF9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNDBfYSA8LSBzc2EoCiAgICB4MCA9IHgwX2EsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzQwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNDBfYSA8LSBvdXRfMTAwXzQwX2EkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzQwX2FbW2ldXSA8LSBzaW1fZGF0YV80MF9hCn0KCnNpbV9vdXRwdXRfNDBfYSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNDBfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF80MF9hIDwtIHNpbV9vdXRwdXRfNDBfYSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNDBfYQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzQwX2EgPC0gc2ltX291dHB1dF80MF9hICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNDApCnNpbV9zdW1tYXJ5XzQwX2EKYGBgCgojIyMjIDUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNTAgPC0gcGFybXMKcGFybXNfNTAkb21lZ2EgPC0gMS81MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzUwX2EgPC0gbGlzdCgpCnNpbV9saXN0XzUwX2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF81MF9hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV81MF9hIDwtIG91dF8xMDBfNTBfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNTBfYVtbaV1dIDwtIHNpbV9kYXRhXzUwX2EKfQoKc2ltX291dHB1dF81MF9hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF81MF9hKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzUwX2EgPC0gc2ltX291dHB1dF81MF9hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF81MF9hCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNTBfYSA8LSBzaW1fb3V0cHV0XzUwX2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS81MCkKc2ltX3N1bW1hcnlfNTBfYQpgYGAKCiMjIyMgNjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc182MCA8LSBwYXJtcwpwYXJtc182MCRvbWVnYSA8LSAxLzYwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNjBfYSA8LSBsaXN0KCkKc2ltX2xpc3RfNjBfYSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYSA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYSA8LSBjKE5fYSAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYSkKCiAgbmFtZXMoeDBfYSkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzYwX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc182MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzYwX2EgPC0gb3V0XzEwMF82MF9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF82MF9hW1tpXV0gPC0gc2ltX2RhdGFfNjBfYQp9CgpzaW1fb3V0cHV0XzYwX2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzYwX2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNjBfYSA8LSBzaW1fb3V0cHV0XzYwX2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzYwX2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV82MF9hIDwtIHNpbV9vdXRwdXRfNjBfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzYwKQpzaW1fc3VtbWFyeV82MF9hCmBgYAoKIyMjIyA3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzcwIDwtIHBhcm1zCnBhcm1zXzcwJG9tZWdhIDwtIDEvNzAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF83MF9hIDwtIGxpc3QoKQpzaW1fbGlzdF83MF9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNzBfYSA8LSBzc2EoCiAgICB4MCA9IHgwX2EsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNzBfYSA8LSBvdXRfMTAwXzcwX2EkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzcwX2FbW2ldXSA8LSBzaW1fZGF0YV83MF9hCn0KCnNpbV9vdXRwdXRfNzBfYSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNzBfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF83MF9hIDwtIHNpbV9vdXRwdXRfNzBfYSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNzBfYQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzcwX2EgPC0gc2ltX291dHB1dF83MF9hICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0KS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNzApCnNpbV9zdW1tYXJ5XzcwX2EKYGBgCgojIyMjIDgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfODAgPC0gcGFybXMKcGFybXNfODAkb21lZ2EgPC0gMS84MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzgwX2EgPC0gbGlzdCgpCnNpbV9saXN0XzgwX2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF84MF9hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV84MF9hIDwtIG91dF8xMDBfODBfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfODBfYVtbaV1dIDwtIHNpbV9kYXRhXzgwX2EKfQoKc2ltX291dHB1dF84MF9hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF84MF9hKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzgwX2EgPC0gc2ltX291dHB1dF84MF9hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF84MF9hCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfODBfYSA8LSBzaW1fb3V0cHV0XzgwX2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfODBfYQpgYGAKCiMjIyMgMTUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTUwIDwtIHBhcm1zCnBhcm1zXzE1MCRvbWVnYSA8LSAxLzE1MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE1MF9hIDwtIGxpc3QoKQpzaW1fbGlzdF8xNTBfYSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYSA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYSA8LSBjKE5fYSAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYSkKCiAgbmFtZXMoeDBfYSkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzE1MF9hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTUwX2EgPC0gb3V0XzEwMF8xNTBfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTUwX2FbW2ldXSA8LSBzaW1fZGF0YV8xNTBfYQp9CgpzaW1fb3V0cHV0XzE1MF9hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNTBfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNTBfYSA8LSBzaW1fb3V0cHV0XzE1MF9hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNTBfYQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE1MF9hIDwtIHNpbV9vdXRwdXRfMTUwX2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNTApCnNpbV9zdW1tYXJ5XzE1MF9hCmBgYAoKIyMjIyAxODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xODAgPC0gcGFybXMKcGFybXNfMTgwJG9tZWdhIDwtIDEvMTgwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTgwX2EgPC0gbGlzdCgpCnNpbV9saXN0XzE4MF9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTgwX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xODBfYSA8LSBvdXRfMTAwXzE4MF9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xODBfYVtbaV1dIDwtIHNpbV9kYXRhXzE4MF9hCn0KCnNpbV9vdXRwdXRfMTgwX2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE4MF9hKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE4MF9hIDwtIHNpbV9vdXRwdXRfMTgwX2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE4MF9hCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTgwX2EgPC0gc2ltX291dHB1dF8xODBfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE4MCkKc2ltX3N1bW1hcnlfMTgwX2EKYGBgCgoKIyMjIyAzNjUgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zNjUgPC0gcGFybXMKcGFybXNfMzY1JG9tZWdhIDwtIDEvMzY1CgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMzY1X2EgPC0gbGlzdCgpCnNpbV9saXN0XzM2NV9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMzY1X2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18zNjUsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zNjVfYSA8LSBvdXRfMTAwXzM2NV9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zNjVfYVtbaV1dIDwtIHNpbV9kYXRhXzM2NV9hCn0KCnNpbV9vdXRwdXRfMzY1X2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzM2NV9hKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzM2NV9hIDwtIHNpbV9vdXRwdXRfMzY1X2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzM2NV9hCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMzY1X2EgPC0gc2ltX291dHB1dF8zNjVfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzM2NSkKc2ltX3N1bW1hcnlfMzY1X2EKYGBgCgoKCiMjIyMgUmVzdWx0cwpgYGB7cn0Kd2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2EgPC0gc2ltX3N1bW1hcnlfYSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMV9hKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19hKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfN19hKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTBfYSkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzIwX2EpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zMF9hKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNDBfYSkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzUwX2EpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV82MF9hKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNzBfYSkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzgwX2EpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNTBfYSkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE4MF9hKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMzY1X2EpICU+JQogIG11dGF0ZShpbW11bml0eV9kdXJhdGlvbiA9IDEvb21lZ2EpICU+JQogIGFycmFuZ2UoaW1tdW5pdHlfZHVyYXRpb24pICU+JQogIG11dGF0ZShtb2RlbD0ic2luZ2xlIiwKICAgICAgICAgcGF0Y2hlcyA9IDMpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2EsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL1Jlc3VsdHMvd2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2EuY3N2IikKCndhbmluZ19yZXN1bHRzX3NpbmdsZV9hCgpgYGAKCmBgYHtyfQpnZ3Bsb3Qod2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2EsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgc3VtX3BlcnNpc3QpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX2J3KCkKYGBgCgojIyA3LVBhdGNoIFNpbmdsZSBQb3B1bGF0aW9uCgo8PDw8PDw8IEhFQUQKVGhlIHNhbWUgc2luZ2xlIHBvcHVsYXRpb24gbW9kZWwgd2FzIHJ1biB3aXRoICROJCBkZWZpbmVkIGFzIHRoZSBzdW0gb2YgNyByYW5kb21seSBzZWxlY3RlZCBjYW1wIHNpemVzLgoKPT09PT09PQo+Pj4+Pj4+IDY3MjcyODAyOGYxOGIyZmMyMjQzMjI5OTNkMjQ1YzlhNmVlNzFiZjEKIyMjIE1vZGVsIFNldC11cAoKTW9kZWwgd2FzIHNldCB1cCB3aXRoIGEgc2luZ2xlIHJhbmRvbWx5IHNlbGVjdGVkIGNhbXAgc2l6ZSB3aXRoIGEgc2luZ2xlIGluZmVjdGVkIGluZGl2aWR1YWwgYW5kIHBhcmFtZXRlcnMgZm9yIHBhdGhvZ2VuIFguIAoKYGBge3J9CiMgRGVmaW5lIFBhcmFtZW50ZXJzCjw8PDw8PDwgSEVBRApOX2IgPC0gICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFRvdGFsIFBvcHVsYXRpb24gc2l6ZSBvZiB0aHJlZSBjYW1wcwo9PT09PT09Ck5fYiA8LSAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgUG9wdWxhdGlvbiBzaXplCj4+Pj4+Pj4gNjcyNzI4MDI4ZjE4YjJmYzIyNDMyMjk5M2QyNDVjOWE2ZWU3MWJmMQppbml0aWFsX2luZmVjdGVkIDwtICAxICAgICMgSW5pdGlhbCBpbmZlY3RlZApzaW1OYW1lIDwtICJTRUlSUyBtb2RlbCIgICAgICAgIyBTaW11bGF0aW9uIG5hbWUKdGYgPC0gMzY1KjMKCiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXMgPC0gbGlzdCgKICBiZXRhID0gMC42LAogIHNpZ21hID0gMC4xNzUsICAgICAgICAgICAgICAgICAgICAgICAgICAjIEUgdG8gSSByYXRlCiAgZ2FtbWEgPSAwLjIsICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBJIHRvIFIgcmF0ZQogIG9tZWdhID0gMS8xMDAsICAgICAgICAgICAgICAgICAgICAgICAgICMgUiB0byBTIHJhdGUKICBtdSA9IGRlbW9fc3VtJEJpcnRoX3JhdGVfZGFpbHlfTWVhbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aC9kZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQogIGFscGhhID0gMS8xMDAwKSAKCiNDcmVhdGUgdGhlIG5hbWVkIGluaXRpYWwgc3RhdGUgdmVjdG9yIGZvciB0aGUgVS1wYXRjaCBzeXN0ZW0uCgp4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKIyBEZWZpbmUgdGhlIHN0YXRlIGNoYW5nZSBtYXRyaXggZm9yIGEgc2luZ2xlIHBhdGNoCm51IDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICAwLCAgMCwgIyBFCiAgICAgICAgICAgICAgICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsIC0xLCAjIEkKICAgICAgICAgICAgICAgIDAsICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICMgUiAKICAgICAgICAgICAgICAgIDAsICAwLCAgMCwgIDAsICsxLCAtMSAsLTEsIC0xLCAtMSwgLTEpLCAjIE4KICAgICAgICAgICAgIG5yb3c9NSxieXJvdz1UUlVFKQoKIyBEZWZpbmUgcHJvcGVuc2l0eSBmdW5jdGlvbnMKYSA8LWMoCiAgICAgICAgcGFzdGUwKCIoYmV0YSpJL04pKlMiKSwgIyBJbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoInNpZ21hKkUiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJlY29tZXMgaW5mZWNpb3VzCiAgICAgICAgcGFzdGUwKCJnYW1tYSpJIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBSZWNvdmVyeSBmcm9tIGluZmVjdGlvbgogICAgICAgIHBhc3RlMCgib21lZ2EqUiIpLCAgICAgICAjIExvc3Mgb2YgaW1tdW5pdHkKICAgICAgICBwYXN0ZTAoIm11Kk4iKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGhzCiAgICAgICAgcGFzdGUwKCJtdSpTIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFMpCiAgICAgICAgcGFzdGUwKCJtdSpFIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEUpCiAgICAgICAgcGFzdGUwKCJtdSpJIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEkpCiAgICAgICAgcGFzdGUwKCJtdSpSIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFIpCiAgICAgICAgcGFzdGUwKCJhbHBoYSpJIikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgZnJvbSBpbmZlY3Rpb24KICAgICAgICAKICAgICAgKQoKYGBgCgoKIyMjIFJ1biBTaW5nbGUgUG9wdWxhdGlvbiBNb2RlbApgYGB7cn0KCkVJRV9zaW5nbGUgPC0gRUlFKFIwX3NpbmdsZSwgcGFybXMpICMgcHJvcG9ydGlvbiBvZiBleHBlY3RlZCBpbmZlY3RlZHMgYXQgZXF1aWxpYnJpdW0KRUlFX3NpbmdsZQoKZXhwZXh0ZWRfaW5mZWN0ZWRzIDwtIEVJRV9zaW5nbGUqTl9iICMgbnVtYmVyIG9mIGV4cGVjdGVkIGluZmVjdGVkcyBhdCBlcXVpbGlicml1bQpleHBleHRlZF9pbmZlY3RlZHMKCnNxcnQoTl9iKSAjIG1hZ25pdHVkZSBvZiBvc2NpbGxhdGlvbnMgCmBgYAoKYGBge3J9CiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjEpCm91dF9iIDwtIHNzYSgKICB4MCA9IHgwX2IsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopIAoKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfYiA8LSBvdXRfYiRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKc2luZ2xlX3Bsb3RfYiA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9iLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC44KSsKICBsYWJzKHg9IlRpbWUgKERheXMpIiwKICAgICAgIHk9Ik51bWJlciBvZiBJbmRpdmlkdWFscyIsIAogICAgICAgY29sb3VyPSJTdGF0ZSIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGV4cGV4dGVkX2luZmVjdGVkcywgbGluZXR5cGUgPSAnZGFzaGVkJykgKwogIHRoZW1lX2J3KCkKCnNpbmdsZV9wbG90X2IKYGBgCgpgYGB7cn0KcGxvdF9kYXRhX2IgJT4lCiAgZmlsdGVyKHN0YXRlID09ICJJIikgJT4lCiAgc2xpY2VfbWF4KGNvdW50KQpgYGAKT3V0YnJlYWsgcGVha2VkIGF0IGRheSAzMiB3aXRoIDMxIGluZmVjdGVkIGluZGl2aWR1YWxzLgoKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X2IgPC0gbGlzdCgpCnNpbV9saXN0X2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgCiAgTl9iIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKICBuYW1lcyh4MF9iKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIHNldC5zZWVkKGkpCiAgb3V0XzEwMF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9iIDwtIG91dF8xMDBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfYltbaV1dIDwtIHNpbV9kYXRhX2IKfQoKc2ltX291dHB1dF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X2IgPC0gc2ltX291dHB1dF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKaGVhZChzaW1fb3V0cHV0X2IpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfYiA8LSBzaW1fb3V0cHV0X2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMDApCnNpbV9zdW1tYXJ5X2IKYGBgCgojIyMgVmFyeWluZyB3YWluaW5nIGltbXVuaXR5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQpXYW5pbmcgaW1tdW5pdHkgd2FzIHRob3VnaHQgdG8gcGxheSBhbiBpbXBvcnRhbnQgcm9sZSBpbiB0aGUgcGVyc2lzdGVuY2Ugb2YgcGF0aG9nZW4gWCBzbyB3ZSBpbmNyZW1lbnRhbGx5IGluY3JlYXNlZCB0aGUgZHVyYXRpb24gb2YgaW1tdW5pdHkgKGJ5IGRlY3JlYXNpbmcgJFxvbWVnYSQpIGFuZCBjYWxjdWxhdGVkIHRoZSBwcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzIGluIDEwMDAgc3RvY2hhc3RpYyBzaW11bGF0aW9ucy4gRHVyYXRpb24gb2YgaW1tdW5pdHkgd2FzIGluY3JlYXNlZCBmcm9tIDEgZGF5IHRvIGEgeWVhci4KCiMjIyMgMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzAgPC0gcGFybXMKcGFybXNfMCRvbWVnYSA8LSAwCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8wX2IgPC0gbGlzdCgpCnNpbV9saXN0XzBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8wX2IgPC0gb3V0XzEwMF8wX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzBfYltbaV1dIDwtIHNpbV9kYXRhXzBfYgp9CgpzaW1fb3V0cHV0XzBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzBfYiA8LSBzaW1fb3V0cHV0XzBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMF9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMF9iIDwtIHNpbV9vdXRwdXRfMF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDApCnNpbV9zdW1tYXJ5XzBfYgpgYGAKCgoKCiMjIyMgMSBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEgPC0gcGFybXMKcGFybXNfMSRvbWVnYSA8LSAxCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xX2IgPC0gbGlzdCgpCnNpbV9saXN0XzFfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzFfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xX2IgPC0gb3V0XzEwMF8xX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzFfYltbaV1dIDwtIHNpbV9kYXRhXzFfYgp9CgpzaW1fb3V0cHV0XzFfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMV9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzFfYiA8LSBzaW1fb3V0cHV0XzFfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMV9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMV9iIDwtIHNpbV9vdXRwdXRfMV9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEpCnNpbV9zdW1tYXJ5XzFfYgpgYGAKCgoKCgojIyMjIDMgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zIDwtIHBhcm1zCnBhcm1zXzMkb21lZ2EgPC0gMS8zCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX2IgPC0gbGlzdCgpCnNpbV9saXN0XzNfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzNfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX2IgPC0gb3V0XzEwMF8zX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfYltbaV1dIDwtIHNpbV9kYXRhXzNfYgp9CgpzaW1fb3V0cHV0XzNfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfYiA8LSBzaW1fb3V0cHV0XzNfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19iIDwtIHNpbV9vdXRwdXRfM19iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMykKc2ltX3N1bW1hcnlfM19iCmBgYAoKIyMjIyA3IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNyA8LSBwYXJtcwpwYXJtc183JG9tZWdhIDwtIDEvNwoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfN19iIDwtIGxpc3QoKQpzaW1fbGlzdF83X2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzdfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzcsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83X2IgPC0gb3V0XzEwMF83X2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzdfYltbaV1dIDwtIHNpbV9kYXRhXzdfYgp9CgpzaW1fb3V0cHV0XzdfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfN19iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzdfYiA8LSBzaW1fb3V0cHV0XzdfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfN19iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfN19iIDwtIHNpbV9vdXRwdXRfN19iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNykKc2ltX3N1bW1hcnlfN19iCmBgYAoKIyMjIyAxMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEwIDwtIHBhcm1zCnBhcm1zXzEwJG9tZWdhIDwtIDEvMTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xMF9iIDwtIGxpc3QoKQpzaW1fbGlzdF8xMF9iIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9iIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKICBuYW1lcyh4MF9iKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzEwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTBfYiA8LSBvdXRfMTAwXzEwX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzEwX2JbW2ldXSA8LSBzaW1fZGF0YV8xMF9iCn0KCnNpbV9vdXRwdXRfMTBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTBfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xMF9iIDwtIHNpbV9vdXRwdXRfMTBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTBfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzEwX2IgPC0gc2ltX291dHB1dF8xMF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTApCnNpbV9zdW1tYXJ5XzEwX2IKYGBgCgojIyMjIDIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMjAgPC0gcGFybXMKcGFybXNfMjAkb21lZ2EgPC0gMS8yMAoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMjBfYiA8LSBsaXN0KCkKc2ltX2xpc3RfMjBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzIwX2IgPC0gc3NhKAogICAgeDAgPSB4MF9iLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18yMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzIwX2IgPC0gb3V0XzEwMF8yMF9iJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8yMF9iW1tpXV0gPC0gc2ltX2RhdGFfMjBfYgp9CgpzaW1fb3V0cHV0XzIwX2IgPC0gYmluZF9yb3dzKHNpbV9saXN0XzIwX2IpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMjBfYiA8LSBzaW1fb3V0cHV0XzIwX2IgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzIwX2IKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8yMF9iIDwtIHNpbV9vdXRwdXRfMjBfYiAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIwKQpzaW1fc3VtbWFyeV8yMF9iCmBgYAoKIyMjIyAzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzMwIDwtIHBhcm1zCnBhcm1zXzMwJG9tZWdhIDwtIDEvMzAKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzMwX2IgPC0gbGlzdCgpCnNpbV9saXN0XzMwX2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2IgPC0gYyhOX2IgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2IpCgogIG5hbWVzKHgwX2IpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zMF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zMF9iIDwtIG91dF8xMDBfMzBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMzBfYltbaV1dIDwtIHNpbV9kYXRhXzMwX2IKfQoKc2ltX291dHB1dF8zMF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zMF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzMwX2IgPC0gc2ltX291dHB1dF8zMF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zMF9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMzBfYiA8LSBzaW1fb3V0cHV0XzMwX2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zMCkKc2ltX3N1bW1hcnlfMzBfYgpgYGAKCiMjIyMgNDAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc180MCA8LSBwYXJtcwpwYXJtc180MCRvbWVnYSA8LSAxLzQwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNDBfYiA8LSBsaXN0KCkKc2ltX2xpc3RfNDBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzQwX2IgPC0gc3NhKAogICAgeDAgPSB4MF9iLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc180MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzQwX2IgPC0gb3V0XzEwMF80MF9iJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF80MF9iW1tpXV0gPC0gc2ltX2RhdGFfNDBfYgp9CgpzaW1fb3V0cHV0XzQwX2IgPC0gYmluZF9yb3dzKHNpbV9saXN0XzQwX2IpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNDBfYiA8LSBzaW1fb3V0cHV0XzQwX2IgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzQwX2IKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV80MF9iIDwtIHNpbV9vdXRwdXRfNDBfYiAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzQwKQpzaW1fc3VtbWFyeV80MF9iCmBgYAoKIyMjIyA1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzUwIDwtIHBhcm1zCnBhcm1zXzUwJG9tZWdhIDwtIDEvNTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF81MF9iIDwtIGxpc3QoKQpzaW1fbGlzdF81MF9iIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9iIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKICBuYW1lcyh4MF9iKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNTBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNTBfYiA8LSBvdXRfMTAwXzUwX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzUwX2JbW2ldXSA8LSBzaW1fZGF0YV81MF9iCn0KCnNpbV9vdXRwdXRfNTBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNTBfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF81MF9iIDwtIHNpbV9vdXRwdXRfNTBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNTBfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzUwX2IgPC0gc2ltX291dHB1dF81MF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNTApCnNpbV9zdW1tYXJ5XzUwX2IKYGBgCgojIyMjIDYwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNjAgPC0gcGFybXMKcGFybXNfNjAkb21lZ2EgPC0gMS82MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzYwX2IgPC0gbGlzdCgpCnNpbV9saXN0XzYwX2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2IgPC0gYyhOX2IgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2IpCgogIG5hbWVzKHgwX2IpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF82MF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV82MF9iIDwtIG91dF8xMDBfNjBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNjBfYltbaV1dIDwtIHNpbV9kYXRhXzYwX2IKfQoKc2ltX291dHB1dF82MF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF82MF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzYwX2IgPC0gc2ltX291dHB1dF82MF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF82MF9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNjBfYiA8LSBzaW1fb3V0cHV0XzYwX2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS82MCkKc2ltX3N1bW1hcnlfNjBfYgpgYGAKCiMjIyMgNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc183MCA8LSBwYXJtcwpwYXJtc183MCRvbWVnYSA8LSAxLzcwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNzBfYiA8LSBsaXN0KCkKc2ltX2xpc3RfNzBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzcwX2IgPC0gc3NhKAogICAgeDAgPSB4MF9iLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc183MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzcwX2IgPC0gb3V0XzEwMF83MF9iJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF83MF9iW1tpXV0gPC0gc2ltX2RhdGFfNzBfYgp9CgpzaW1fb3V0cHV0XzcwX2IgPC0gYmluZF9yb3dzKHNpbV9saXN0XzcwX2IpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNzBfYiA8LSBzaW1fb3V0cHV0XzcwX2IgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzcwX2IKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV83MF9iIDwtIHNpbV9vdXRwdXRfNzBfYiAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcwKQpzaW1fc3VtbWFyeV83MF9iCmBgYAoKIyMjIyA4MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzgwIDwtIHBhcm1zCnBhcm1zXzgwJG9tZWdhIDwtIDEvODAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF84MF9iIDwtIGxpc3QoKQpzaW1fbGlzdF84MF9iIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9iIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKICBuYW1lcyh4MF9iKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfODBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfODBfYiA8LSBvdXRfMTAwXzgwX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzgwX2JbW2ldXSA8LSBzaW1fZGF0YV84MF9iCn0KCnNpbV9vdXRwdXRfODBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfODBfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF84MF9iIDwtIHNpbV9vdXRwdXRfODBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfODBfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzgwX2IgPC0gc2ltX291dHB1dF84MF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvODApCnNpbV9zdW1tYXJ5XzgwX2IKYGBgCgojIyMjIDkwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfOTAgPC0gcGFybXMKcGFybXNfOTAkb21lZ2EgPC0gMS85MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzkwX2IgPC0gbGlzdCgpCnNpbV9saXN0XzkwX2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2IgPC0gYyhOX2IgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2IpCgogIG5hbWVzKHgwX2IpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF85MF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfOTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV85MF9iIDwtIG91dF8xMDBfOTBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfOTBfYltbaV1dIDwtIHNpbV9kYXRhXzkwX2IKfQoKc2ltX291dHB1dF85MF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF85MF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzkwX2IgPC0gc2ltX291dHB1dF85MF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF85MF9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfOTBfYiA8LSBzaW1fb3V0cHV0XzkwX2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS85MCkKc2ltX3N1bW1hcnlfOTBfYgpgYGAKCgojIyMjIDExMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzExMCA8LSBwYXJtcwpwYXJtc18xMTAkb21lZ2EgPC0gMS8xMTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xMTBfYiA8LSBsaXN0KCkKc2ltX2xpc3RfMTEwX2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2IgPC0gYyhOX2IgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2IpCgogIG5hbWVzKHgwX2IpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xMTBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzExMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzExMF9iIDwtIG91dF8xMDBfMTEwX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzExMF9iW1tpXV0gPC0gc2ltX2RhdGFfMTEwX2IKfQoKc2ltX291dHB1dF8xMTBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTEwX2IpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTEwX2IgPC0gc2ltX291dHB1dF8xMTBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTEwX2IKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xMTBfYiA8LSBzaW1fb3V0cHV0XzExMF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTEwKQpzaW1fc3VtbWFyeV8xMTBfYgpgYGAKCiMjIyMgMTIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTIwIDwtIHBhcm1zCnBhcm1zXzEyMCRvbWVnYSA8LSAxLzEyMAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzEyMF9iIDwtIGxpc3QoKQpzaW1fbGlzdF8xMjBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzEyMF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTIwX2IgPC0gb3V0XzEwMF8xMjBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTIwX2JbW2ldXSA8LSBzaW1fZGF0YV8xMjBfYgp9CgpzaW1fb3V0cHV0XzEyMF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xMjBfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xMjBfYiA8LSBzaW1fb3V0cHV0XzEyMF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xMjBfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzEyMF9iIDwtIHNpbV9vdXRwdXRfMTIwX2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMjApCnNpbV9zdW1tYXJ5XzEyMF9iCmBgYAoKIyMjIyAxMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xMzAgPC0gcGFybXMKcGFybXNfMTMwJG9tZWdhIDwtIDEvMTMwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTMwX2IgPC0gbGlzdCgpCnNpbV9saXN0XzEzMF9iIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9iIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKICBuYW1lcyh4MF9iKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTMwX2IgPC0gc3NhKAogICAgeDAgPSB4MF9iLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xMzBfYiA8LSBvdXRfMTAwXzEzMF9iJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xMzBfYltbaV1dIDwtIHNpbV9kYXRhXzEzMF9iCn0KCnNpbV9vdXRwdXRfMTMwX2IgPC0gYmluZF9yb3dzKHNpbV9saXN0XzEzMF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzEzMF9iIDwtIHNpbV9vdXRwdXRfMTMwX2IgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzEzMF9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTMwX2IgPC0gc2ltX291dHB1dF8xMzBfYiAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEzMCkKc2ltX3N1bW1hcnlfMTMwX2IKYGBgCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE1MCA8LSBwYXJtcwpwYXJtc18xNTAkb21lZ2EgPC0gMS8xNTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNTBfYiA8LSBsaXN0KCkKc2ltX2xpc3RfMTUwX2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2IgPC0gYyhOX2IgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2IpCgogIG5hbWVzKHgwX2IpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xNTBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzE1MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE1MF9iIDwtIG91dF8xMDBfMTUwX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE1MF9iW1tpXV0gPC0gc2ltX2RhdGFfMTUwX2IKfQoKc2ltX291dHB1dF8xNTBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTUwX2IpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTUwX2IgPC0gc2ltX291dHB1dF8xNTBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTUwX2IKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNTBfYiA8LSBzaW1fb3V0cHV0XzE1MF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTUwKQpzaW1fc3VtbWFyeV8xNTBfYgpgYGAKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTgwIDwtIHBhcm1zCnBhcm1zXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE4MF9iIDwtIGxpc3QoKQpzaW1fbGlzdF8xODBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzE4MF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTgwX2IgPC0gb3V0XzEwMF8xODBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTgwX2JbW2ldXSA8LSBzaW1fZGF0YV8xODBfYgp9CgpzaW1fb3V0cHV0XzE4MF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xODBfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xODBfYiA8LSBzaW1fb3V0cHV0XzE4MF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xODBfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE4MF9iIDwtIHNpbV9vdXRwdXRfMTgwX2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xODApCnNpbV9zdW1tYXJ5XzE4MF9iCmBgYAoKCiMjIyMgMzY1IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMzY1IDwtIHBhcm1zCnBhcm1zXzM2NSRvbWVnYSA8LSAxLzM2NQoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzM2NV9iIDwtIGxpc3QoKQpzaW1fbGlzdF8zNjVfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzM2NV9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMzY1LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMzY1X2IgPC0gb3V0XzEwMF8zNjVfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMzY1X2JbW2ldXSA8LSBzaW1fZGF0YV8zNjVfYgp9CgpzaW1fb3V0cHV0XzM2NV9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zNjVfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zNjVfYiA8LSBzaW1fb3V0cHV0XzM2NV9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zNjVfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzM2NV9iIDwtIHNpbV9vdXRwdXRfMzY1X2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5XzM2NV9iCmBgYAoKCgojIyMjIFJlc3VsdHMKYGBge3J9CndhbmluZ19yZXN1bHRzX3NpbmdsZV9iIDwtIHNpbV9zdW1tYXJ5X2IgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzFfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzdfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzEwX2IpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8yMF9iKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMzBfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzQwX2IpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV81MF9iKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNjBfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzcwX2IpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV84MF9iKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfOTBfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzExMF9iKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTIwX2IpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xMzBfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE1MF9iKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTgwX2IpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zNjVfYikgJT4lCiAgbXV0YXRlKGltbXVuaXR5X2R1cmF0aW9uID0gMS9vbWVnYSkgJT4lCiAgYXJyYW5nZShpbW11bml0eV9kdXJhdGlvbikgJT4lCiAgbXV0YXRlKG1vZGVsPSJzaW5nbGUiLAogICAgICAgICBwYXRjaGVzID0gNykKCndyaXRlX2Nzdih3YW5pbmdfcmVzdWx0c19zaW5nbGVfYiwgZmlsZSA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUmVzdWx0cy93YW5pbmdfcmVzdWx0c19zaW5nbGVfYi5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2IKCmBgYAoKYGBge3J9CmdncGxvdCh3YW5pbmdfcmVzdWx0c19zaW5nbGVfYiwgYWVzKGltbXVuaXR5X2R1cmF0aW9uLCBzdW1fcGVyc2lzdCkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfYncoKQpgYGAKCiMjIDE0LVBhdGNoIFNpbmdsZSBQb3B1bGF0aW9uCgo8PDw8PDw8IEhFQUQKVGhlIHNhbWUgc2luZ2xlIHBvcHVsYXRpb24gbW9kZWwgd2FzIHJhbiB3aXRoICROJCBkZWZpbmVkIGFzIHRoZSBzdW0gb2YgMTQgcmFuZG9tbHkgc2FtcGxlZCBjYW1wIHNpemVzLgoKPT09PT09PQo+Pj4+Pj4+IDY3MjcyODAyOGYxOGIyZmMyMjQzMjI5OTNkMjQ1YzlhNmVlNzFiZjEKIyMjIE1vZGVsIFNldC11cAoKTW9kZWwgd2FzIHNldCB1cCB3aXRoIGEgc2luZ2xlIHJhbmRvbWx5IHNlbGVjdGVkIGNhbXAgc2l6ZSB3aXRoIGEgc2luZ2xlIGluZmVjdGVkIGluZGl2aWR1YWwgYW5kIHBhcmFtZXRlcnMgZm9yIHBhdGhvZ2VuIFguIAoKYGBge3J9CiMgRGVmaW5lIFBhcmFtZW50ZXJzCjw8PDw8PDwgSEVBRApOX2MgPC0gICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBUb3RhbCBQb3B1bGF0aW9uIHNpemUgb2YgdGhyZWUgY2FtcHMKPT09PT09PQpOX2MgPC0gICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBQb3B1bGF0aW9uIHNpemUKPj4+Pj4+PiA2NzI3MjgwMjhmMThiMmZjMjI0MzIyOTkzZDI0NWM5YTZlZTcxYmYxCmluaXRpYWxfaW5mZWN0ZWQgPC0gIDEgICAgIyBJbml0aWFsIGluZmVjdGVkCnNpbU5hbWUgPC0gIlNFSVJTIG1vZGVsIiAgICAgICAjIFNpbXVsYXRpb24gbmFtZQp0ZiA8LSAzNjUqMwoKI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtcyA8LSBsaXN0KAogIGJldGEgPSAwLjYsCiAgc2lnbWEgPSAwLjE3NSwgICAgICAgICAgICAgICAgICAgICAgICAgICMgRSB0byBJIHJhdGUKICBnYW1tYSA9IDAuMiwgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEkgdG8gUiByYXRlCiAgb21lZ2EgPSAxLzEwMCwgICAgICAgICAgICAgICAgICAgICAgICAgIyBSIHRvIFMgcmF0ZQogIG11ID0gZGVtb19zdW0kQmlydGhfcmF0ZV9kYWlseV9NZWFuLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRoL2RlYXRoIHJhdGUgcGVyIHBlcnNvbiBwZXIgZGF5CiAgYWxwaGEgPSAxLzEwMDApIAoKI0NyZWF0ZSB0aGUgbmFtZWQgaW5pdGlhbCBzdGF0ZSB2ZWN0b3IgZm9yIHRoZSBVLXBhdGNoIHN5c3RlbS4KCngwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgpuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgojIERlZmluZSB0aGUgc3RhdGUgY2hhbmdlIG1hdHJpeCBmb3IgYSBzaW5nbGUgcGF0Y2gKbnUgPC0gbWF0cml4KGMoIC0xLCAgMCwgIDAsICsxLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAjIFMKICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwphIDwtYygKICAgICAgICBwYXN0ZTAoIihiZXRhKkkvTikqUyIpLCAjIEluZmVjdGlvbgogICAgICAgIHBhc3RlMCgic2lnbWEqRSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmVjb21lcyBpbmZlY2lvdXMKICAgICAgICBwYXN0ZTAoImdhbW1hKkkiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFJlY292ZXJ5IGZyb20gaW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJvbWVnYSpSIiksICAgICAgICMgTG9zcyBvZiBpbW11bml0eQogICAgICAgIHBhc3RlMCgibXUqTiIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aHMKICAgICAgICBwYXN0ZTAoIm11KlMiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUykKICAgICAgICBwYXN0ZTAoIm11KkUiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoRSkKICAgICAgICBwYXN0ZTAoIm11KkkiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoSSkKICAgICAgICBwYXN0ZTAoIm11KlIiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUikKICAgICAgICBwYXN0ZTAoImFscGhhKkkiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyBmcm9tIGluZmVjdGlvbgogICAgICAgIAogICAgICApCgpgYGAKCgojIyMgUnVuIFNpbmdsZSBQb3B1bGF0aW9uIE1vZGVsCmBgYHtyfQoKRUlFX3NpbmdsZSA8LSBFSUUoUjBfc2luZ2xlLCBwYXJtcykgIyBwcm9wb3J0aW9uIG9mIGV4cGVjdGVkIGluZmVjdGVkcyBhdCBlcXVpbGlicml1bQpFSUVfc2luZ2xlCgpleHBleHRlZF9pbmZlY3RlZHMgPC0gRUlFX3NpbmdsZSpOX2MgIyBudW1iZXIgb2YgZXhwZWN0ZWQgaW5mZWN0ZWRzIGF0IGVxdWlsaWJyaXVtCmV4cGV4dGVkX2luZmVjdGVkcwoKc3FydChOX2MpICMgbWFnbml0dWRlIG9mIG9zY2lsbGF0aW9ucyAKYGBgCgpgYGB7cn0KIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZAo8PDw8PDw8IEhFQUQKc2V0LnNlZWQoMjUpCj09PT09PT0Kc2V0LnNlZWQoMjEpCj4+Pj4+Pj4gNjcyNzI4MDI4ZjE4YjJmYzIyNDMyMjk5M2QyNDVjOWE2ZWU3MWJmMQpvdXRfYyA8LSBzc2EoCiAgeDAgPSB4MF9jLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtcywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKSAKCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX2MgPC0gb3V0X2MkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnNpbmdsZV9wbG90X2MgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfYywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKGFscGhhPTAuOCkrCiAgbGFicyh4PSJUaW1lIChEYXlzKSIsCiAgICAgICB5PSJOdW1iZXIgb2YgSW5kaXZpZHVhbHMiLCAKICAgICAgIGNvbG91cj0iU3RhdGUiKSsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBleHBleHRlZF9pbmZlY3RlZHMsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpICsKICB0aGVtZV9idygpCgpzaW5nbGVfcGxvdF9jCmBgYAoKYGBge3J9CnBsb3RfZGF0YV9jICU+JQogIGZpbHRlcihzdGF0ZSA9PSAiSSIpICU+JQogIHNsaWNlX21heChjb3VudCkKYGBgCk91dGJyZWFrIHBlYWtlZCBhdCBkYXkgMzIgd2l0aCAzMSBpbmZlY3RlZCBpbmRpdmlkdWFscy4KCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9jIDwtIGxpc3QoKQpzaW1fbGlzdF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgc2V0LnNlZWQoaSkKICBvdXRfMTAwX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtcywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX2MgPC0gb3V0XzEwMF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9jW1tpXV0gPC0gc2ltX2RhdGFfYwp9CgpzaW1fb3V0cHV0X2MgPC0gYmluZF9yb3dzKHNpbV9saXN0X2MpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfYyA8LSBzaW1fb3V0cHV0X2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpoZWFkKHNpbV9vdXRwdXRfYykKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9jIDwtIHNpbV9vdXRwdXRfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnlfYwpgYGAKCiMjIyBWYXJ5aW5nIHdhaW5pbmcgaW1tdW5pdHkgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9CldhbmluZyBpbW11bml0eSB3YXMgdGhvdWdodCB0byBwbGF5IGFuIGltcG9ydGFudCByb2xlIGluIHRoZSBwZXJzaXN0ZW5jZSBvZiBwYXRob2dlbiBYIHNvIHdlIGluY3JlbWVudGFsbHkgaW5jcmVhc2VkIHRoZSBkdXJhdGlvbiBvZiBpbW11bml0eSAoYnkgZGVjcmVhc2luZyAkXG9tZWdhJCkgYW5kIGNhbGN1bGF0ZWQgdGhlIHByb2JhYmlsaXR5IG9mIHBlcnNpc3RlbmNlIGFmdGVyIDMgeWVhcnMgaW4gMTAwMCBzdG9jaGFzdGljIHNpbXVsYXRpb25zLiBEdXJhdGlvbiBvZiBpbW11bml0eSB3YXMgaW5jcmVhc2VkIGZyb20gMSBkYXkgdG8gYSB5ZWFyLgoKIyMjIyAwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMCA8LSBwYXJtcwpwYXJtc18wJG9tZWdhIDwtIDAKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzBfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8wX2MgPC0gb3V0XzEwMF8wX2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzBfY1tbaV1dIDwtIHNpbV9kYXRhXzBfYwp9CgpzaW1fb3V0cHV0XzBfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzBfYyA8LSBzaW1fb3V0cHV0XzBfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMF9jIDwtIHNpbV9vdXRwdXRfMF9jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDApCnNpbV9zdW1tYXJ5XzBfYwpgYGAKCgoKCiMjIyMgMSBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEgPC0gcGFybXMKcGFybXNfMSRvbWVnYSA8LSAxCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xX2MgPC0gbGlzdCgpCnNpbV9saXN0XzFfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMV9jIDwtIG91dF8xMDBfMV9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xX2NbW2ldXSA8LSBzaW1fZGF0YV8xX2MKfQoKc2ltX291dHB1dF8xX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzFfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xX2MgPC0gc2ltX291dHB1dF8xX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzFfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzFfYyA8LSBzaW1fb3V0cHV0XzFfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxKQpzaW1fc3VtbWFyeV8xX2MKYGBgCgoKCgoKIyMjIyAzIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMyA8LSBwYXJtcwpwYXJtc18zJG9tZWdhIDwtIDEvMwoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19jIDwtIGxpc3QoKQpzaW1fbGlzdF8zX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfM19jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfYyA8LSBvdXRfMTAwXzNfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19jW1tpXV0gPC0gc2ltX2RhdGFfM19jCn0KCnNpbV9vdXRwdXRfM19jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX2MpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19jIDwtIHNpbV9vdXRwdXRfM19jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX2MKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX2MgPC0gc2ltX291dHB1dF8zX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zKQpzaW1fc3VtbWFyeV8zX2MKYGBgCgojIyMjIDcgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc183IDwtIHBhcm1zCnBhcm1zXzckb21lZ2EgPC0gMS83CgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF83X2MgPC0gbGlzdCgpCnNpbV9saXN0XzdfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzdfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzcsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83X2MgPC0gb3V0XzEwMF83X2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzdfY1tbaV1dIDwtIHNpbV9kYXRhXzdfYwp9CgpzaW1fb3V0cHV0XzdfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfN19jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzdfYyA8LSBzaW1fb3V0cHV0XzdfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfN19jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfN19jIDwtIHNpbV9vdXRwdXRfN19jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNykKc2ltX3N1bW1hcnlfN19jCmBgYAoKIyMjIyAxMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEwIDwtIHBhcm1zCnBhcm1zXzEwJG9tZWdhIDwtIDEvMTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xMF9jIDwtIGxpc3QoKQpzaW1fbGlzdF8xMF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzEwX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzEwX2MgPC0gb3V0XzEwMF8xMF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xMF9jW1tpXV0gPC0gc2ltX2RhdGFfMTBfYwp9CgpzaW1fb3V0cHV0XzEwX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzEwX2MpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTBfYyA8LSBzaW1fb3V0cHV0XzEwX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzEwX2MKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xMF9jIDwtIHNpbV9vdXRwdXRfMTBfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwKQpzaW1fc3VtbWFyeV8xMF9jCmBgYAoKIyMjIyAyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzIwIDwtIHBhcm1zCnBhcm1zXzIwJG9tZWdhIDwtIDEvMjAKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzIwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzIwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMjBfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMjBfYyA8LSBvdXRfMTAwXzIwX2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzIwX2NbW2ldXSA8LSBzaW1fZGF0YV8yMF9jCn0KCnNpbV9vdXRwdXRfMjBfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMjBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8yMF9jIDwtIHNpbV9vdXRwdXRfMjBfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMjBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzIwX2MgPC0gc2ltX291dHB1dF8yMF9jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjApCnNpbV9zdW1tYXJ5XzIwX2MKYGBgCgojIyMjIDMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMzAgPC0gcGFybXMKcGFybXNfMzAkb21lZ2EgPC0gMS8zMAoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMzBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMzBfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zMF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zMF9jIDwtIG91dF8xMDBfMzBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMzBfY1tbaV1dIDwtIHNpbV9kYXRhXzMwX2MKfQoKc2ltX291dHB1dF8zMF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zMF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzMwX2MgPC0gc2ltX291dHB1dF8zMF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zMF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMzBfYyA8LSBzaW1fb3V0cHV0XzMwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zMCkKc2ltX3N1bW1hcnlfMzBfYwpgYGAKCiMjIyMgNDAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc180MCA8LSBwYXJtcwpwYXJtc180MCRvbWVnYSA8LSAxLzQwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNDBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfNDBfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF80MF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNDAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV80MF9jIDwtIG91dF8xMDBfNDBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNDBfY1tbaV1dIDwtIHNpbV9kYXRhXzQwX2MKfQoKc2ltX291dHB1dF80MF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF80MF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzQwX2MgPC0gc2ltX291dHB1dF80MF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF80MF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNDBfYyA8LSBzaW1fb3V0cHV0XzQwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS80MCkKc2ltX3N1bW1hcnlfNDBfYwpgYGAKCiMjIyMgNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc181MCA8LSBwYXJtcwpwYXJtc181MCRvbWVnYSA8LSAxLzUwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNTBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfNTBfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF81MF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV81MF9jIDwtIG91dF8xMDBfNTBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNTBfY1tbaV1dIDwtIHNpbV9kYXRhXzUwX2MKfQoKc2ltX291dHB1dF81MF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF81MF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzUwX2MgPC0gc2ltX291dHB1dF81MF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF81MF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNTBfYyA8LSBzaW1fb3V0cHV0XzUwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS81MCkKc2ltX3N1bW1hcnlfNTBfYwpgYGAKCiMjIyMgNjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc182MCA8LSBwYXJtcwpwYXJtc182MCRvbWVnYSA8LSAxLzYwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNjBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfNjBfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF82MF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV82MF9jIDwtIG91dF8xMDBfNjBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNjBfY1tbaV1dIDwtIHNpbV9kYXRhXzYwX2MKfQoKc2ltX291dHB1dF82MF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF82MF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzYwX2MgPC0gc2ltX291dHB1dF82MF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF82MF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNjBfYyA8LSBzaW1fb3V0cHV0XzYwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS82MCkKc2ltX3N1bW1hcnlfNjBfYwpgYGAKCiMjIyMgNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc183MCA8LSBwYXJtcwpwYXJtc183MCRvbWVnYSA8LSAxLzcwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNzBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfNzBfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF83MF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83MF9jIDwtIG91dF8xMDBfNzBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNzBfY1tbaV1dIDwtIHNpbV9kYXRhXzcwX2MKfQoKc2ltX291dHB1dF83MF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF83MF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzcwX2MgPC0gc2ltX291dHB1dF83MF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF83MF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNzBfYyA8LSBzaW1fb3V0cHV0XzcwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83MCkKc2ltX3N1bW1hcnlfNzBfYwpgYGAKCiMjIyMgODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc184MCA8LSBwYXJtcwpwYXJtc184MCRvbWVnYSA8LSAxLzgwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfODBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfODBfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF84MF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV84MF9jIDwtIG91dF8xMDBfODBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfODBfY1tbaV1dIDwtIHNpbV9kYXRhXzgwX2MKfQoKc2ltX291dHB1dF84MF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF84MF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzgwX2MgPC0gc2ltX291dHB1dF84MF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF84MF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfODBfYyA8LSBzaW1fb3V0cHV0XzgwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfODBfYwpgYGAKCiMjIyMgOTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc185MCA8LSBwYXJtcwpwYXJtc185MCRvbWVnYSA8LSAxLzkwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfOTBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfOTBfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF85MF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfOTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV85MF9jIDwtIG91dF8xMDBfOTBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfOTBfY1tbaV1dIDwtIHNpbV9kYXRhXzkwX2MKfQoKc2ltX291dHB1dF85MF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF85MF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzkwX2MgPC0gc2ltX291dHB1dF85MF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF85MF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfOTBfYyA8LSBzaW1fb3V0cHV0XzkwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS85MCkKc2ltX3N1bW1hcnlfOTBfYwpgYGAKCgojIyMjIDExMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzExMCA8LSBwYXJtcwpwYXJtc18xMTAkb21lZ2EgPC0gMS8xMTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xMTBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMTEwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTEwX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xMTBfYyA8LSBvdXRfMTAwXzExMF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xMTBfY1tbaV1dIDwtIHNpbV9kYXRhXzExMF9jCn0KCnNpbV9vdXRwdXRfMTEwX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzExMF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzExMF9jIDwtIHNpbV9vdXRwdXRfMTEwX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzExMF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTEwX2MgPC0gc2ltX291dHB1dF8xMTBfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzExMCkKc2ltX3N1bW1hcnlfMTEwX2MKYGBgCgojIyMjIDEyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEyMCA8LSBwYXJtcwpwYXJtc18xMjAkb21lZ2EgPC0gMS8xMjAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xMjBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMTIwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTIwX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xMjBfYyA8LSBvdXRfMTAwXzEyMF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xMjBfY1tbaV1dIDwtIHNpbV9kYXRhXzEyMF9jCn0KCnNpbV9vdXRwdXRfMTIwX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzEyMF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzEyMF9jIDwtIHNpbV9vdXRwdXRfMTIwX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzEyMF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTIwX2MgPC0gc2ltX291dHB1dF8xMjBfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEyMCkKc2ltX3N1bW1hcnlfMTIwX2MKYGBgCgojIyMjIDEzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEzMCA8LSBwYXJtcwpwYXJtc18xMzAkb21lZ2EgPC0gMS8xMzAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xMzBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMTMwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTMwX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xMzBfYyA8LSBvdXRfMTAwXzEzMF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xMzBfY1tbaV1dIDwtIHNpbV9kYXRhXzEzMF9jCn0KCnNpbV9vdXRwdXRfMTMwX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzEzMF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzEzMF9jIDwtIHNpbV9vdXRwdXRfMTMwX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzEzMF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTMwX2MgPC0gc2ltX291dHB1dF8xMzBfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEzMCkKc2ltX3N1bW1hcnlfMTMwX2MKYGBgCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE1MCA8LSBwYXJtcwpwYXJtc18xNTAkb21lZ2EgPC0gMS8xNTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNTBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMTUwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTUwX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNTBfYyA8LSBvdXRfMTAwXzE1MF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNTBfY1tbaV1dIDwtIHNpbV9kYXRhXzE1MF9jCn0KCnNpbV9vdXRwdXRfMTUwX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE1MF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE1MF9jIDwtIHNpbV9vdXRwdXRfMTUwX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE1MF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTUwX2MgPC0gc2ltX291dHB1dF8xNTBfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE1MCkKc2ltX3N1bW1hcnlfMTUwX2MKYGBgCgojIyMjIDE4MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE4MCA8LSBwYXJtcwpwYXJtc18xODAkb21lZ2EgPC0gMS8xODAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xODBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMTgwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTgwX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xODBfYyA8LSBvdXRfMTAwXzE4MF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xODBfY1tbaV1dIDwtIHNpbV9kYXRhXzE4MF9jCn0KCnNpbV9vdXRwdXRfMTgwX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE4MF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE4MF9jIDwtIHNpbV9vdXRwdXRfMTgwX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE4MF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTgwX2MgPC0gc2ltX291dHB1dF8xODBfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE4MCkKc2ltX3N1bW1hcnlfMTgwX2MKYGBgCgojIyMjIDIyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzIyMCA8LSBwYXJtcwpwYXJtc18yMjAkb21lZ2EgPC0gMS8yMjAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8yMjBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMjIwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMjIwX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18yMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8yMjBfYyA8LSBvdXRfMTAwXzIyMF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8yMjBfY1tbaV1dIDwtIHNpbV9kYXRhXzIyMF9jCn0KCnNpbV9vdXRwdXRfMjIwX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzIyMF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzIyMF9jIDwtIHNpbV9vdXRwdXRfMjIwX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzIyMF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMjIwX2MgPC0gc2ltX291dHB1dF8yMjBfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIyMCkKc2ltX3N1bW1hcnlfMjIwX2MKYGBgCgojIyMjIDI3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzI3MCA8LSBwYXJtcwpwYXJtc18yNzAkb21lZ2EgPC0gMS8yNzAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8yNzBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMjcwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMjcwX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18yNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8yNzBfYyA8LSBvdXRfMTAwXzI3MF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8yNzBfY1tbaV1dIDwtIHNpbV9kYXRhXzI3MF9jCn0KCnNpbV9vdXRwdXRfMjcwX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzI3MF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzI3MF9jIDwtIHNpbV9vdXRwdXRfMjcwX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzI3MF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMjcwX2MgPC0gc2ltX291dHB1dF8yNzBfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzI3MCkKc2ltX3N1bW1hcnlfMjcwX2MKYGBgCgojIyMjIDM2NSBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzM2NSA8LSBwYXJtcwpwYXJtc18zNjUkb21lZ2EgPC0gMS8zNjUKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zNjVfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMzY1X2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMzY1X2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18zNjUsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zNjVfYyA8LSBvdXRfMTAwXzM2NV9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zNjVfY1tbaV1dIDwtIHNpbV9kYXRhXzM2NV9jCn0KCnNpbV9vdXRwdXRfMzY1X2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzM2NV9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzM2NV9jIDwtIHNpbV9vdXRwdXRfMzY1X2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzM2NV9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMzY1X2MgPC0gc2ltX291dHB1dF8zNjVfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzM2NSkKc2ltX3N1bW1hcnlfMzY1X2MKYGBgCgoKCiMjIyMgUmVzdWx0cwpgYGB7cn0Kd2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2MgPC0gc2ltX3N1bW1hcnlfYyAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMV9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfN19jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTBfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzIwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zMF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNDBfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzUwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV82MF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNzBfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzgwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV85MF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTEwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xMjBfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzEzMF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTUwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xODBfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzIyMF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMjcwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zNjVfYykgJT4lCiAgbXV0YXRlKGltbXVuaXR5X2R1cmF0aW9uID0gMS9vbWVnYSkgJT4lCiAgYXJyYW5nZShpbW11bml0eV9kdXJhdGlvbikgJT4lCiAgbXV0YXRlKG1vZGVsPSJzaW5nbGUiLAogICAgICAgICBwYXRjaGVzID0gMTQpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2MsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL1Jlc3VsdHMvd2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2MuY3N2IikKCndhbmluZ19yZXN1bHRzX3NpbmdsZV9jCgpgYGAKCmBgYHtyfQpnZ3Bsb3Qod2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2MsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgc3VtX3BlcnNpc3QpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX2J3KCkKYGBgCiMjIENvbWJpbmVkIE1ldGEgYW5kIFNpbmdsZSBSZXN1bHRzCmBgYHtyfQpjb21iaW5lZF93YW5pbmdfMiA8LSByZWFkX2NzdigiUmVzdWx0cy9jb21iaW5lZF93YW5pbmdfcmVzdWx0cy5jc3YiKSU+JQogIGJpbmRfcm93cyh3YW5pbmdfcmVzdWx0c19zaW5nbGVfYSkgJT4lCiAgYmluZF9yb3dzKHdhbmluZ19yZXN1bHRzX3NpbmdsZV9iKSAlPiUKICBiaW5kX3Jvd3Mod2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2MpCgpjb21iaW5lZF93YW5pbmdfMgoKd3JpdGVfY3N2KGNvbWJpbmVkX3dhbmluZ18yLCAiUmVzdWx0cy9jb21iaW5lZF93YW5pbmdfcmVzdWx0c18yLmNzdiIpCmBgYAoKYGBge3J9Cgpjb21iaW5lZF9wbG90XzIgPC0gZ2dwbG90KGNvbWJpbmVkX3dhbmluZ18yLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIHN1bV9wZXJzaXN0LCBjb2xvdXIgPSBhcy5mYWN0b3IocGF0Y2hlcyksIGxpbmV0eXBlID0gbW9kZWwpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC45LCBzaXplPTEpKwogICNnZW9tX3BvaW50KGFscGhhPTAuNSwgc2l6ZT0xLjUpKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDM2MCwgNTApKSArCiAgbGFicyh4ID0gIkR1cmF0aW9uIG9mIGltbXVuaXR5IChkYXlzKSIsCiAgICAgICB5ID0gIlByb2JhYmlsaXR5IG9mIHBlcnNpc3RlbmNlIGFmdGVyIDMgeWVhcnMgKCUpIiwgCiAgICAgICBjb2xvdXIgPSAiTm8uIENhbXBzIiwKICAgICAgIGxpbmV0eXBlID0gIk1vZGVsIFR5cGUiKSsKICBzY2FsZV9jb2xvcl9kaXNjcmV0ZSh0eXBlID0gcGFsLAogICAgICAgICAgICAgICAgICAgICAgICAgI3dlc19wYWxldHRlcyRBc3Rlcm9pZENpdHkzLAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIjEiLCAiMyIsICI3IiwgIjE0IikpKwogIHNjYWxlX2xpbmV0eXBlX2Rpc2NyZXRlKGxhYmVscyA9IGMoIk1ldGFwb3B1bGF0aW9uIiwgIlNpbmdsZSBQb3B1bGF0aW9uIikpICsKICB0aGVtZV9idygpCgpjb21iaW5lZF9wbG90XzIKYGBgCmBgYHtyfQpnZ3NhdmUoZmlsZW5hbWUgPSAiY29tYmluZWRfcGxvdF9wYXRjaGVzXzIucGRmIiwgcGxvdCA9IGNvbWJpbmVkX3Bsb3RfMiwgZGV2aWNlID0gInBkZiIsIHdpZHRoID0gNywgaGVpZ2h0ID0gNSwgcGF0aCA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUGxvdHMiKQpgYGAKCmBgYHtyfQpwYXRob2dlblhfcmVzdWx0cyA8LSBjb21iaW5lZF93YW5pbmdfMiAlPiUKICBmaWx0ZXIob21lZ2EgPT0gMC4wMSkKCnBhdGhvZ2VuWF9yZXN1bHRzCmBgYAoKCmBgYHtyfQpwYXRob2dlblhfYmFyIDwtIGdncGxvdChwYXRob2dlblhfcmVzdWx0cywgYWVzKGFzLmZhY3RvcihwYXRjaGVzKSwgc3VtX3BlcnNpc3QsIGdyb3VwTmFtZSA9IG1vZGVsLCBmaWxsID0gbW9kZWwpKSArCiAgZ2VvbV9jb2wocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSwgY29sb3VyID0gImJsYWNrIikgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHggPSAiTm8uIENhbXBzIiwKICAgICAgIHkgPSAiUHJvYmFiaWxpdHkgb2YgcGVyc2lzdGVuY2UgYWZ0ZXIgMyB5ZWFycyAoJSkiLAogICAgICAgZmlsbCA9ICJNb2RlbCBUeXBlIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUoCiAgICB0eXBlID0gd2VzX3BhbGV0dGVzJEFzdGVyb2lkQ2l0eTMsCiAgICBsYWJlbHMgPSBjKCJNZXRhcG9wdWxhdGlvbiIsICJTaW5nbGUgUG9wdWxhdGlvbiIpKSArCiAgdGhlbWVfYncoKQoKcGF0aG9nZW5YX2JhcgpgYGAKYGBge3J9Cmdnc2F2ZShmaWxlbmFtZSA9ICJwYXRob2dlblhfYmFyLnBkZiIsIHBsb3QgPSBwYXRob2dlblhfYmFyLCBkZXZpY2UgPSAicGRmIiwgd2lkdGggPSA3LCBoZWlnaHQgPSA0LCBwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscy9QbG90cyIpCgpgYGAKCiMjIENvbWJpbmVkIHBsb3RzCmBgYHtyfQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShncmlkKQp0aGVtZV9zZXQodGhlbWVfcHVicigpKQoKZG91YmxlX2NvbWJpbmVkX3Bsb3QgPC0gZ2dhcnJhbmdlKGNvbWJpbmVkX3Bsb3QgKyBycmVtb3ZlKCJ4bGFiIikgKyBycmVtb3ZlKCJ5bGFiIiksIGNvbWJpbmVkX3Bsb3RfMiArIHJyZW1vdmUoInhsYWIiKSArIHJyZW1vdmUoInlsYWIiKSwKICAgICAgICAgIGxhYmVscyA9IGMoIkEiLCAiQiIpLAogICAgICAgICAgZm9udC5sYWJlbCA9IGxpc3Qoc2l6ZSA9IDEyLCBmYWNlID0gInBsYWluIiksCiAgICAgICAgICB2anVzdCA9IDEsCiAgICAgICAgICBuY29sID0gMiwgbnJvdyA9IDEsCiAgICAgICAgICBsZWdlbmQuZ3JvYiA9IGdldF9sZWdlbmQoY29tYmluZWRfcGxvdF8yKSwKICAgICAgICAgIGxlZ2VuZCA9ICJyaWdodCIKICAgICAgICAgICkKCmRvdWJsZV9jb21iaW5lZF9wbG90IDwtIGFubm90YXRlX2ZpZ3VyZShkb3VibGVfY29tYmluZWRfcGxvdCwgbGVmdCA9IHRleHRHcm9iKCJQcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzICglKSIsIHJvdCA9IDkwLCB2anVzdCA9IDEsIGdwID0gZ3BhcihjZXggPSAxKSksCiAgICAgICAgICAgICAgICAgICAgYm90dG9tID0gdGV4dEdyb2IoIkR1cmF0aW9uIG9mIGltbXVuaXR5IChkYXlzKSIsIGhqdXN0ID0gMC44LCBncCA9IGdwYXIoY2V4ID0gMSkpKQoKZG91YmxlX2NvbWJpbmVkX3Bsb3QKYGBgCmBgYHtyfQpnZ3NhdmUoZmlsZW5hbWUgPSAiZG91YmxlX2ltbXVuaXR5X3Bsb3QucGRmIiwgcGxvdCA9IGRvdWJsZV9jb21iaW5lZF9wbG90LCBkZXZpY2UgPSAicGRmIiwgd2lkdGggPSA4LCBoZWlnaHQgPSA0LCBwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscy9QbG90cyIpCmBgYAoKCgojIyBSZWZlcmVuY2VzCgoK